Merge ssh://gitolite.kernel.org/pub/scm/network/iproute2/iproute2-next

This commit is contained in:
Stephen Hemminger 2024-09-18 08:45:43 -07:00
commit 8b9d9ea427
16 changed files with 203 additions and 62 deletions

View File

@ -28,9 +28,6 @@ enum vlan_show_subject {
#define VLAN_ID_LEN 9
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
static void usage(void)
{
fprintf(stderr,
@ -587,7 +584,7 @@ static void open_vlan_port(int ifi_index, enum vlan_show_subject subject)
{
open_json_object(NULL);
print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname",
"%-" __stringify(IFNAMSIZ) "s ",
"%-" textify(IFNAMSIZ) "s ",
ll_index_to_name(ifi_index));
open_json_array(PRINT_JSON,
subject == VLAN_SHOW_VLAN ? "vlans": "tunnels");
@ -651,7 +648,7 @@ static void print_vlan_tunnel_info(struct rtattr *tb, int ifindex)
opened = true;
} else {
print_string(PRINT_FP, NULL,
"%-" __stringify(IFNAMSIZ) "s ", "");
"%-" textify(IFNAMSIZ) "s ", "");
}
open_json_object(NULL);
@ -724,13 +721,13 @@ static void print_vlan_flags(__u16 flags)
static void __print_one_vlan_stats(const struct bridge_vlan_xstats *vstats)
{
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", "");
print_lluint(PRINT_ANY, "rx_bytes", "RX: %llu bytes",
vstats->rx_bytes);
print_lluint(PRINT_ANY, "rx_packets", " %llu packets\n",
vstats->rx_packets);
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", "");
print_lluint(PRINT_ANY, "tx_bytes", "TX: %llu bytes",
vstats->tx_bytes);
print_lluint(PRINT_ANY, "tx_packets", " %llu packets\n",
@ -784,7 +781,7 @@ static void print_vlan_stats_attr(struct rtattr *attr, int ifindex)
found_vlan = true;
} else {
print_string(PRINT_FP, NULL,
"%-" __stringify(IFNAMSIZ) "s ", "");
"%-" textify(IFNAMSIZ) "s ", "");
}
print_one_vlan_stats(vstats);
}
@ -830,7 +827,7 @@ static void print_vlan_router_ports(struct rtattr *rattr)
int rem = RTA_PAYLOAD(rattr);
struct rtattr *i;
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", "");
open_json_array(PRINT_ANY, is_json_context() ? "router_ports" :
"router ports: ");
for (i = RTA_DATA(rattr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
@ -842,7 +839,7 @@ static void print_vlan_router_ports(struct rtattr *rattr)
print_nl();
/* start: IFNAMSIZ + 4 + strlen("router ports: ") */
print_string(PRINT_FP, NULL,
"%-" __stringify(IFNAMSIZ) "s "
"%-" textify(IFNAMSIZ) "s "
" ",
"");
}
@ -880,11 +877,11 @@ static void print_vlan_global_opts(struct rtattr *a, int ifindex)
vlan_rtm_cur_ifidx = ifindex;
} else {
open_json_object(NULL);
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", "");
}
print_range("vlan", vid, vrange);
print_nl();
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", "");
if (vtb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]) {
vattr = vtb[BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING];
print_uint(PRINT_ANY, "mcast_snooping", "mcast_snooping %u ",
@ -1025,12 +1022,12 @@ static void print_vlan_opts(struct rtattr *a, int ifindex)
vlan_rtm_cur_ifidx = ifindex;
} else {
open_json_object(NULL);
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", "");
}
print_range("vlan", vinfo->vid, vrange);
print_vlan_flags(vinfo->flags);
print_nl();
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", "");
print_stp_state(state);
if (vtb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER]) {
vattr = vtb[BRIDGE_VLANDB_ENTRY_MCAST_ROUTER];
@ -1168,8 +1165,8 @@ static int vlan_show(int argc, char **argv, int subject)
}
if (!is_json_context()) {
printf("%-" __stringify(IFNAMSIZ) "s %-"
__stringify(VLAN_ID_LEN) "s", "port",
printf("%-" textify(IFNAMSIZ) "s %-"
textify(VLAN_ID_LEN) "s", "port",
"vlan-id");
printf("\n");
}
@ -1196,8 +1193,8 @@ static int vlan_show(int argc, char **argv, int subject)
}
if (!is_json_context()) {
printf("%-" __stringify(IFNAMSIZ) "s %-"
__stringify(VLAN_ID_LEN) "s", "port",
printf("%-" textify(IFNAMSIZ) "s %-"
textify(VLAN_ID_LEN) "s", "port",
"vlan-id");
if (subject == VLAN_SHOW_TUNNELINFO)
printf(" tunnel-id");
@ -1220,7 +1217,7 @@ static int vlan_show(int argc, char **argv, int subject)
}
if (!is_json_context())
printf("%-" __stringify(IFNAMSIZ) "s vlan-id\n",
printf("%-" textify(IFNAMSIZ) "s vlan-id\n",
"port");
if (rtnl_dump_filter(&rth, print_vlan_stats, stdout) < 0) {
@ -1282,8 +1279,8 @@ static int vlan_global_show(int argc, char **argv)
}
if (!is_json_context()) {
printf("%-" __stringify(IFNAMSIZ) "s %-"
__stringify(VLAN_ID_LEN) "s", "port",
printf("%-" textify(IFNAMSIZ) "s %-"
textify(VLAN_ID_LEN) "s", "port",
"vlan-id");
printf("\n");
}
@ -1331,7 +1328,7 @@ static void print_vlan_info(struct rtattr *tb, int ifindex)
opened = true;
} else {
print_string(PRINT_FP, NULL, "%-"
__stringify(IFNAMSIZ) "s ", "");
textify(IFNAMSIZ) "s ", "");
}
open_json_object(NULL);

View File

@ -27,9 +27,6 @@ static unsigned int filter_index;
/* max len of "<start>-<end>" */
#define VXLAN_ID_LEN 17
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
static void usage(void)
{
fprintf(stderr,
@ -153,7 +150,7 @@ static void open_vni_port(int ifi_index)
{
open_json_object(NULL);
print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname",
"%-" __stringify(IFNAMSIZ) "s ",
"%-" textify(IFNAMSIZ) "s ",
ll_index_to_name(ifi_index));
open_json_array(PRINT_JSON, "vnis");
}
@ -174,7 +171,7 @@ static void print_vnifilter_entry_stats(struct rtattr *stats_attr)
RTA_PAYLOAD(stats_attr), NLA_F_NESTED);
print_nl();
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s RX: ",
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s RX: ",
"");
if (stb[VNIFILTER_ENTRY_STATS_RX_BYTES]) {
@ -195,7 +192,7 @@ static void print_vnifilter_entry_stats(struct rtattr *stats_attr)
}
print_nl();
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s TX: ",
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s TX: ",
"");
if (stb[VNIFILTER_ENTRY_STATS_TX_BYTES]) {
@ -327,7 +324,7 @@ int print_vnifilter_rtm(struct nlmsghdr *n, void *arg)
open_vni_port(tmsg->ifindex);
opened = true;
} else {
print_string(PRINT_FP, NULL, "%-" __stringify(IFNAMSIZ) "s ", "");
print_string(PRINT_FP, NULL, "%-" textify(IFNAMSIZ) "s ", "");
}
print_vni(t, tmsg->ifindex);
@ -373,8 +370,8 @@ static int vni_show(int argc, char **argv)
}
if (!is_json_context())
printf("%-" __stringify(IFNAMSIZ) "s %-"
__stringify(VXLAN_ID_LEN) "s group/remote\n", "dev",
printf("%-" textify(IFNAMSIZ) "s %-"
textify(VXLAN_ID_LEN) "s group/remote\n", "dev",
"vni");
ret = rtnl_dump_filter(&rth, print_vnifilter_rtm, NULL);

View File

@ -2851,7 +2851,7 @@ union bpf_attr {
* **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**,
* **TCP_NODELAY**, **TCP_MAXSEG**, **TCP_WINDOW_CLAMP**,
* **TCP_THIN_LINEAR_TIMEOUTS**, **TCP_BPF_DELACK_MAX**,
* **TCP_BPF_RTO_MIN**.
* **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**.
* * **IPPROTO_IP**, which supports *optname* **IP_TOS**.
* * **IPPROTO_IPV6**, which supports the following *optname*\ s:
* **IPV6_TCLASS**, **IPV6_AUTOFLOWLABEL**.
@ -7080,6 +7080,7 @@ enum {
TCP_BPF_SYN = 1005, /* Copy the TCP header */
TCP_BPF_SYN_IP = 1006, /* Copy the IP[46] and TCP header */
TCP_BPF_SYN_MAC = 1007, /* Copy the MAC, IP[46], and TCP header */
TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */
};
enum {

View File

@ -230,8 +230,8 @@ struct tpacket_hdr_v1 {
* ts_first_pkt:
* Is always the time-stamp when the block was opened.
* Case a) ZERO packets
* No packets to deal with but atleast you know the
* time-interval of this block.
* No packets to deal with but at least you know
* the time-interval of this block.
* Case b) Non-zero packets
* Use the ts of the first packet in the block.
*
@ -265,7 +265,8 @@ enum tpacket_versions {
- struct tpacket_hdr
- pad to TPACKET_ALIGNMENT=16
- struct sockaddr_ll
- Gap, chosen so that packet data (Start+tp_net) alignes to TPACKET_ALIGNMENT=16
- Gap, chosen so that packet data (Start+tp_net) aligns to
TPACKET_ALIGNMENT=16
- Start+tp_mac: [ Optional MAC header ]
- Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16.
- Pad to align to TPACKET_ALIGNMENT=16

View File

@ -141,7 +141,7 @@ struct in_addr {
*/
#define IP_PMTUDISC_INTERFACE 4
/* weaker version of IP_PMTUDISC_INTERFACE, which allows packets to get
* fragmented if they exeed the interface mtu
* fragmented if they exceed the interface mtu
*/
#define IP_PMTUDISC_OMIT 5

View File

@ -143,7 +143,7 @@ enum {
INET_DIAG_SHUTDOWN,
/*
* Next extenstions cannot be requested in struct inet_diag_req_v2:
* Next extensions cannot be requested in struct inet_diag_req_v2:
* its field idiag_ext has only 8 bits.
*/

View File

@ -50,6 +50,12 @@ enum {
IOAM6_IPTUNNEL_FREQ_K, /* u32 */
IOAM6_IPTUNNEL_FREQ_N, /* u32 */
/* Tunnel src address.
* For encap,auto modes.
* Optional (automatic if not provided).
*/
IOAM6_IPTUNNEL_SRC, /* struct in6_addr */
__IOAM6_IPTUNNEL_MAX,
};

View File

@ -16,10 +16,15 @@ struct nhmsg {
struct nexthop_grp {
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
__u8 resvd1;
__u8 weight_high; /* high order bits of weight */
__u16 resvd2;
};
static __inline__ __u16 nexthop_grp_weight(const struct nexthop_grp *entry)
{
return ((entry->weight_high << 8) | entry->weight) + 1;
}
enum {
NEXTHOP_GRP_TYPE_MPATH, /* hash-threshold nexthop group
* default type if not specified
@ -33,6 +38,9 @@ enum {
#define NHA_OP_FLAG_DUMP_STATS BIT(0)
#define NHA_OP_FLAG_DUMP_HW_STATS BIT(1)
/* Response OP_FLAGS. */
#define NHA_OP_FLAG_RESP_GRP_RESVD_0 BIT(31) /* Dump clears resvd fields. */
enum {
NHA_UNSPEC,
NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */

View File

@ -246,16 +246,19 @@ struct tc_u32_key {
};
struct tc_u32_sel {
unsigned char flags;
unsigned char offshift;
unsigned char nkeys;
/* New members MUST be added within the __struct_group() macro below. */
__struct_group(tc_u32_sel_hdr, hdr, /* no attrs */,
unsigned char flags;
unsigned char offshift;
unsigned char nkeys;
__be16 offmask;
__u16 off;
short offoff;
__be16 offmask;
__u16 off;
short offoff;
short hoff;
__be32 hmask;
short hoff;
__be32 hmask;
);
struct tc_u32_key keys[];
};

View File

@ -166,6 +166,12 @@ static void netkit_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
print_string(PRINT_ANY, "policy", "policy %s ",
netkit_print_policy(policy));
}
if (tb[IFLA_NETKIT_PEER_POLICY]) {
__u32 policy = rta_getattr_u32(tb[IFLA_NETKIT_PEER_POLICY]);
print_string(PRINT_ANY, "peer_policy", "peer policy %s ",
netkit_print_policy(policy));
}
}
static void netkit_print_help(struct link_util *lu,

View File

@ -234,6 +234,24 @@ static bool __valid_nh_group_attr(const struct rtattr *g_attr)
return num && num * sizeof(struct nexthop_grp) == RTA_PAYLOAD(g_attr);
}
static __u16 nhgrp_weight(__u32 resp_op_flags,
const struct nexthop_grp *nhgrp)
{
__u16 weight = nhgrp->weight_high;
if (!(resp_op_flags & NHA_OP_FLAG_RESP_GRP_RESVD_0))
weight = 0;
return ((weight << 8) | nhgrp->weight) + 1;
}
static void nhgrp_set_weight(struct nexthop_grp *nhgrp, __u16 weight)
{
weight--;
nhgrp->weight_high = weight >> 8;
nhgrp->weight = weight & 0xff;
}
static void print_nh_group(const struct nh_entry *nhe)
{
int i;
@ -247,9 +265,10 @@ static void print_nh_group(const struct nh_entry *nhe)
print_string(PRINT_FP, NULL, "%s", "/");
print_uint(PRINT_ANY, "id", "%u", nhe->nh_groups[i].id);
if (nhe->nh_groups[i].weight)
print_uint(PRINT_ANY, "weight", ",%u",
nhe->nh_groups[i].weight + 1);
__u16 weight = nhgrp_weight(nhe->nh_resp_op_flags,
&nhe->nh_groups[i]);
if (weight > 1)
print_uint(PRINT_ANY, "weight", ",%u", weight);
close_json_object();
}
@ -507,6 +526,9 @@ static int ipnh_parse_nhmsg(FILE *fp, const struct nhmsg *nhm, int len,
parse_nh_group_stats_rta(tb[NHA_GROUP_STATS], nhe);
}
nhe->nh_resp_op_flags =
tb[NHA_OP_FLAGS] ? rta_getattr_u32(tb[NHA_OP_FLAGS]) : 0;
nhe->nh_blackhole = !!tb[NHA_BLACKHOLE];
nhe->nh_fdb = !!tb[NHA_FDB];
@ -904,9 +926,9 @@ static int add_nh_group_attr(struct nlmsghdr *n, int maxlen, char *argv)
unsigned int w;
wsep++;
if (get_unsigned(&w, wsep, 0) || w == 0 || w > 256)
if (get_unsigned(&w, wsep, 0) || w == 0 || w > 65536)
invarg("\"weight\" is invalid\n", wsep);
grps[i].weight = w - 1;
nhgrp_set_weight(&grps[i], w);
}
if (!sep)

View File

@ -352,14 +352,25 @@ static void print_encap_ioam6(FILE *fp, struct rtattr *encap)
print_uint(PRINT_ANY, "freqn", "/%u ", freq_n);
mode = rta_getattr_u8(tb[IOAM6_IPTUNNEL_MODE]);
if (!tb[IOAM6_IPTUNNEL_DST] && mode != IOAM6_IPTUNNEL_MODE_INLINE)
if ((tb[IOAM6_IPTUNNEL_SRC] && mode == IOAM6_IPTUNNEL_MODE_INLINE) ||
(!tb[IOAM6_IPTUNNEL_DST] && mode != IOAM6_IPTUNNEL_MODE_INLINE))
return;
print_string(PRINT_ANY, "mode", "mode %s ", format_ioam6mode_type(mode));
if (mode != IOAM6_IPTUNNEL_MODE_INLINE)
print_string(PRINT_ANY, "tundst", "tundst %s ",
rt_addr_n2a_rta(AF_INET6, tb[IOAM6_IPTUNNEL_DST]));
if (mode != IOAM6_IPTUNNEL_MODE_INLINE) {
if (tb[IOAM6_IPTUNNEL_SRC]) {
print_color_string(PRINT_ANY, COLOR_INET6,
"tunsrc", "tunsrc %s ",
rt_addr_n2a_rta(AF_INET6,
tb[IOAM6_IPTUNNEL_SRC]));
}
print_color_string(PRINT_ANY, COLOR_INET6,
"tundst", "tundst %s ",
rt_addr_n2a_rta(AF_INET6,
tb[IOAM6_IPTUNNEL_DST]));
}
trace = RTA_DATA(tb[IOAM6_IPTUNNEL_TRACE]);
@ -1111,11 +1122,12 @@ static int parse_encap_ioam6(struct rtattr *rta, size_t len, int *argcp,
int ns_found = 0, argc = *argcp;
__u16 trace_ns, trace_size = 0;
struct ioam6_trace_hdr *trace;
inet_prefix saddr, daddr;
char **argv = *argvp;
__u32 trace_type = 0;
__u32 freq_k, freq_n;
char buf[16] = {0};
inet_prefix addr;
bool has_src;
__u8 mode;
if (strcmp(*argv, "freq") != 0) {
@ -1158,6 +1170,23 @@ static int parse_encap_ioam6(struct rtattr *rta, size_t len, int *argcp,
NEXT_ARG();
}
if (strcmp(*argv, "tunsrc") != 0) {
has_src = false;
} else {
has_src = true;
if (mode == IOAM6_IPTUNNEL_MODE_INLINE)
invarg("Inline mode does not need tunsrc", *argv);
NEXT_ARG();
get_addr(&saddr, *argv, AF_INET6);
if (saddr.family != AF_INET6 || saddr.bytelen != 16)
invarg("Invalid IPv6 address for tunsrc", *argv);
NEXT_ARG();
}
if (strcmp(*argv, "tundst") != 0) {
if (mode != IOAM6_IPTUNNEL_MODE_INLINE)
missarg("tundst");
@ -1167,8 +1196,8 @@ static int parse_encap_ioam6(struct rtattr *rta, size_t len, int *argcp,
NEXT_ARG();
get_addr(&addr, *argv, AF_INET6);
if (addr.family != AF_INET6 || addr.bytelen != 16)
get_addr(&daddr, *argv, AF_INET6);
if (daddr.family != AF_INET6 || daddr.bytelen != 16)
invarg("Invalid IPv6 address for tundst", *argv);
NEXT_ARG();
@ -1239,8 +1268,10 @@ static int parse_encap_ioam6(struct rtattr *rta, size_t len, int *argcp,
if (rta_addattr32(rta, len, IOAM6_IPTUNNEL_FREQ_K, freq_k) ||
rta_addattr32(rta, len, IOAM6_IPTUNNEL_FREQ_N, freq_n) ||
rta_addattr8(rta, len, IOAM6_IPTUNNEL_MODE, mode) ||
(mode != IOAM6_IPTUNNEL_MODE_INLINE && has_src &&
rta_addattr_l(rta, len, IOAM6_IPTUNNEL_SRC, &saddr.data, saddr.bytelen)) ||
(mode != IOAM6_IPTUNNEL_MODE_INLINE &&
rta_addattr_l(rta, len, IOAM6_IPTUNNEL_DST, &addr.data, addr.bytelen)) ||
rta_addattr_l(rta, len, IOAM6_IPTUNNEL_DST, &daddr.data, daddr.bytelen)) ||
rta_addattr_l(rta, len, IOAM6_IPTUNNEL_TRACE, trace, sizeof(*trace))) {
free(trace);
return -1;

View File

@ -25,6 +25,7 @@ struct nh_entry {
__u32 nh_id;
__u32 nh_oif;
__u32 nh_flags;
__u32 nh_resp_op_flags;
__u16 nh_grp_type;
__u8 nh_family;
__u8 nh_scope;

View File

@ -253,6 +253,8 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.IR K "/" N " ] "
.BR mode " [ "
.BR inline " | " encap " | " auto " ] ["
.B tunsrc
.IR ADDRESS " ] ["
.B tundst
.IR ADDRESS " ] "
.B trace
@ -1037,6 +1039,12 @@ divisible by 8. This attribute can be used only with NEXT-C-SID flavor.
packets.
.sp
.B tunsrc
.I ADDRESS
- IPv6 address of the tunnel source (outer header), not used with inline mode.
It is optional: if not provided, the tunnel source address is chosen
automatically.
.B tundst
.I ADDRESS
- IPv6 address of the tunnel destination (outer header), not used with inline

View File

@ -106,7 +106,9 @@ flower \- flow based traffic control filter
.B l2_miss
.IR L2_MISS " | "
.BR cfm
.IR CFM_OPTIONS " }"
.IR CFM_OPTIONS " | "
.BR enc_flags
.IR ENCFLAG-LIST " }"
.ti -8
.IR LSE_LIST " := [ " LSE_LIST " ] " LSE
@ -131,6 +133,16 @@ flower \- flow based traffic control filter
.B op
.IR OPCODE "
.ti -8
.IR ENCFLAG-LIST " := [ " ENCFLAG-LIST "/ ] " ENCFLAG
.ti -8
.IR ENCFLAG " := { "
.BR [no]tuncsum " | "
.BR [no]tundf " | "
.BR [no]tunoam " | "
.BR [no]tuncrit " } "
.SH DESCRIPTION
The
.B flower
@ -538,11 +550,23 @@ Match on the Maintenance Domain (MD) level field.
.BI op " OPCODE "
Match on the CFM opcode field. \fIOPCODE\fR is an unsigned 8 bit value in
decimal format.
.RE
.TP
.BI enc_flags " ENCFLAG-LIST "
Match on tunnel control flags.
.I ENCFLAG-LIST
is a list of the following tunnel control flags:
.BR [no]tuncsum ", "
.BR [no]tundf ", "
.BR [no]tunoam ", "
.BR [no]tuncrit ", "
each separated by '/'.
.TP
.SH NOTES
As stated above where applicable, matches of a certain layer implicitly depend
on the matches of the next lower layer. Precisely, layer one and two matches
(\fBindev\fR, \fBdst_mac\fR and \fBsrc_mac\fR)
(\fBindev\fR, \fBdst_mac\fR, \fBsrc_mac\fR and \fBenc_flags\fR)
have no dependency,
MPLS and layer three matches
(\fBmpls\fR, \fBmpls_label\fR, \fBmpls_tc\fR, \fBmpls_bos\fR, \fBmpls_ttl\fR,

View File

@ -28,6 +28,7 @@
enum flower_matching_flags {
FLOWER_IP_FLAGS,
FLOWER_ENC_DST_FLAGS,
};
enum flower_endpoint {
@ -99,13 +100,16 @@ static void explain(void)
" ct_label MASKED_CT_LABEL |\n"
" ct_mark MASKED_CT_MARK |\n"
" ct_zone MASKED_CT_ZONE |\n"
" cfm CFM }\n"
" cfm CFM |\n"
" enc_flags ENCFLAG-LIST }\n"
" LSE-LIST := [ LSE-LIST ] LSE\n"
" LSE := lse depth DEPTH { label LABEL | tc TC | bos BOS | ttl TTL }\n"
" FILTERID := X:Y:Z\n"
" MASKED_LLADDR := { LLADDR | LLADDR/MASK | LLADDR/BITS }\n"
" MASKED_CT_STATE := combination of {+|-} and flags trk,est,new,rel,rpl,inv\n"
" CFM := { mdl LEVEL | op OPCODE }\n"
" ENCFLAG-LIST := [ ENCFLAG-LIST/ ]ENCFLAG\n"
" ENCFLAG := { [no]tuncsum | [no]tundf | [no]tunoam | [no]tuncrit }\n"
" ACTION-SPEC := ... look at individual actions\n"
"\n"
"NOTE: CLASSID, IP-PROTO are parsed as hexadecimal input.\n"
@ -205,6 +209,10 @@ struct flag_to_string {
static struct flag_to_string flags_str[] = {
{ TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOWER_IP_FLAGS, "frag" },
{ TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST, FLOWER_IP_FLAGS, "firstfrag" },
{ TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM, FLOWER_ENC_DST_FLAGS, "tuncsum" },
{ TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT, FLOWER_ENC_DST_FLAGS, "tundf" },
{ TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM, FLOWER_ENC_DST_FLAGS, "tunoam" },
{ TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT, FLOWER_ENC_DST_FLAGS, "tuncrit" },
};
static int flower_parse_matching_flags(char *str,
@ -1642,6 +1650,8 @@ static int flower_parse_opt(const struct filter_util *qu, char *handle,
__u32 flags = 0;
__u32 mtf = 0;
__u32 mtf_mask = 0;
__u32 dst_flags = 0;
__u32 dst_flags_mask = 0;
if (handle) {
ret = get_u32(&t->tcm_handle, handle, 0);
@ -2248,6 +2258,17 @@ static int flower_parse_opt(const struct filter_util *qu, char *handle,
fprintf(stderr, "Illegal \"pfcp_opts\"\n");
return -1;
}
} else if (!strcmp(*argv, "enc_flags")) {
NEXT_ARG();
ret = flower_parse_matching_flags(*argv,
FLOWER_ENC_DST_FLAGS,
&dst_flags,
&dst_flags_mask);
if (ret < 0) {
fprintf(stderr, "Illegal \"enc_flags\"\n");
return -1;
}
} else if (matches(*argv, "action") == 0) {
NEXT_ARG();
ret = parse_action(&argc, &argv, TCA_FLOWER_ACT, n);
@ -2286,6 +2307,17 @@ parse_done:
return ret;
}
if (dst_flags_mask) {
ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_ENC_FLAGS,
htonl(dst_flags));
if (ret)
return ret;
ret = addattr32(n, MAX_MSG, TCA_FLOWER_KEY_ENC_FLAGS_MASK,
htonl(dst_flags_mask));
if (ret)
return ret;
}
if (tc_proto != htons(ETH_P_ALL)) {
ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, tc_proto);
if (ret)
@ -3262,6 +3294,10 @@ static int flower_print_opt(const struct filter_util *qu, FILE *f,
tb[TCA_FLOWER_KEY_FLAGS],
tb[TCA_FLOWER_KEY_FLAGS_MASK]);
flower_print_matching_flags("enc_flags", FLOWER_ENC_DST_FLAGS,
tb[TCA_FLOWER_KEY_ENC_FLAGS],
tb[TCA_FLOWER_KEY_ENC_FLAGS_MASK]);
if (tb[TCA_FLOWER_L2_MISS]) {
struct rtattr *attr = tb[TCA_FLOWER_L2_MISS];