Updated static flowspec action definition to the new filter syntax.
case NET_ROA6:
return bsnprintf(buf, buflen, "%I6/%u-%u AS%u", n->roa6.prefix, n->roa6.pxlen, n->roa6.max_pxlen, n->roa6.asn);
case NET_FLOW4:
- return flow4_net_format(buf, buflen, &n->flow4);
+ return flow4_net_format(buf, buflen, &n->flow4, " ");
case NET_FLOW6:
- return flow6_net_format(buf, buflen, &n->flow6);
+ return flow6_net_format(buf, buflen, &n->flow6, " ");
+ case NET_IP6_SADR:
+ return bsnprintf(buf, buflen, "%I6/%d from %I6/%d", n->ip6_sadr.dst_prefix, n->ip6_sadr.dst_pxlen, n->ip6_sadr.src_prefix, n->ip6_sadr.src_pxlen);
case NET_MPLS:
return bsnprintf(buf, buflen, "%u", n->mpls.label);
}
s = ipbuf;
goto str;
+ /* float number formats delegated to stdio */
+ case 'f':
+ memcpy(fmtbuf, percent, (fmt - percent) + 1);
+ snprintf(ipbuf, sizeof(ipbuf), fmtbuf, va_arg(args, double));
+ s = ipbuf;
+ goto str;
++
+ case 't':
+ t = va_arg(args, btime);
+ t1 = t TO_S;
+ t2 = t - t1 S;
+
+ if (precision < 0)
+ precision = 3;
+
+ if (precision > 6)
+ precision = 6;
+
+ /* Compute field_width for second part */
+ if ((precision > 0) && (field_width > 0))
+ field_width -= (1 + precision);
+
+ if (field_width < 0)
+ field_width = 0;
+
+ /* Print seconds */
+ flags |= SIGN;
+ str = number(str, t1, 10, field_width, 0, flags, size);
+ if (!str)
+ return -1;
+
+ if (precision > 0)
+ {
+ size -= (str-start);
+ start = str;
+
+ if ((1 + precision) > size)
+ return -1;
+
+ /* Convert microseconds to requested precision */
+ for (i = precision; i < 6; i++)
+ t2 /= 10;
+
+ /* Print sub-seconds */
+ *str++ = '.';
+ str = number(str, t2, 10, precision, 0, ZEROPAD, size - 1);
+ if (!str)
+ return -1;
+ }
+ goto done;
+
/* integer number formats - set up the flags and "break" */
case 'o':
base = 8;
void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs);
struct nexthop *nh;
- tm_format_datetime(tm, &config->tf_route, e->lastmod);
+ byte ai[1024] = {0};
+ switch (e->net->n.addr->type) {
+ case NET_FLOW4:
+ case NET_FLOW6:
+ rt_flow_action_format(ai, sizeof(ai) - 1, e);
+ break;
+ }
+
+ tm_format_time(tm, &config->tf_route, e->lastmod);
if (ipa_nonzero(a->from) && !ipa_equal(a->from, a->nh.gw))
bsprintf(from, " from %I", a->from);
else
if (d->last_table != d->tab)
rt_show_table(c, d);
- cli_printf(c, -1007, "%-18s%s %s [%s %s%s]%s%s", ia, ai, rta_dest_name(a->dest),
- cli_printf(c, -1007, "%-20s %s [%s %s%s]%s%s", ia, rta_dest_name(a->dest),
++ cli_printf(c, -1007, "%-20s%s %s [%s %s%s]%s%s", ia, ai, rta_dest_name(a->dest),
a->src->proto->name, tm, from, primary ? (sync_error ? " !" : " *") : "", info);
if (a->dest == RTD_UNICAST)
cf_error("Unexpected or missing nexthop/type");
}
- struct f_inst *fic = f_new_inst();
- fic->code = 'C'; fic->a1.p = val;
+static void
+static_flow_action(u64 ec)
+{
+ NEW_F_VAL;
+
+ val->type = T_EC; val->val.ec = ec;
- P('C','a'), 'a',
++ struct f_inst *fic = f_new_inst(FI_CONSTANT_INDIRECT);
++ fic->a1.p = val;
+ *this_srt_last_cmd = f_generate_complex(
++ FI_CLIST_ADD_DEL, 'a',
+ f_new_dynamic_attr(EAF_TYPE_EC_SET, T_ECLIST, EA_CODE(EAP_BGP, BA_EXT_COMMUNITY)),
+ fic
+ );
+ this_srt_last_cmd = &((*this_srt_last_cmd)->next);
+}
+
CF_DECLS
+%type <fl> float_rate
+
CF_KEYWORDS(STATIC, ROUTE, VIA, DROP, REJECT, PROHIBIT, PREFERENCE, CHECK, LINK)
CF_KEYWORDS(ONLINK, WEIGHT, RECURSIVE, IGP, TABLE, BLACKHOLE, UNREACHABLE, BFD, MPLS)
+CF_KEYWORDS(RATE, SAMPLE, LAST, DSCP)
+CF_KEYWORDS_CS(mBps, mbps, Bps, bps, kBps, kbps, MBps, Mbps, GBps, Gbps, TBps, Tbps)
CF_GRAMMAR