Merge branch 'master' into net-next
This commit is contained in:
commit
d5b62e6439
|
|
@ -90,6 +90,9 @@ struct link_util *get_link_slave_kind(const char *slave_kind);
|
|||
|
||||
void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len);
|
||||
|
||||
__u32 ipvrf_get_table(const char *name);
|
||||
bool name_is_vrf(const char *name);
|
||||
|
||||
#ifndef INFINITY_LIFE_TIME
|
||||
#define INFINITY_LIFE_TIME 0xFFFFFFFFU
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static void usage(void)
|
|||
fprintf(stderr, " [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]\n");
|
||||
fprintf(stderr, " ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n");
|
||||
fprintf(stderr, " [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n");
|
||||
fprintf(stderr, " [ label LABEL ] [up] ]\n");
|
||||
fprintf(stderr, " [ label LABEL ] [up] [ vrf NAME ] ]\n");
|
||||
fprintf(stderr, " ip address {showdump|restore}\n");
|
||||
fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n");
|
||||
fprintf(stderr, " [ broadcast ADDR ] [ anycast ADDR ]\n");
|
||||
|
|
@ -1620,6 +1620,16 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
|
|||
if (!ifindex)
|
||||
invarg("Device does not exist\n", *argv);
|
||||
filter.master = ifindex;
|
||||
} else if (strcmp(*argv, "vrf") == 0) {
|
||||
int ifindex;
|
||||
|
||||
NEXT_ARG();
|
||||
ifindex = ll_name_to_index(*argv);
|
||||
if (!ifindex)
|
||||
invarg("Not a valid VRF name\n", *argv);
|
||||
if (!name_is_vrf(*argv))
|
||||
invarg("Not a valid VRF name\n", *argv);
|
||||
filter.master = ifindex;
|
||||
} else if (strcmp(*argv, "type") == 0) {
|
||||
int soff;
|
||||
|
||||
|
|
|
|||
15
ip/iplink.c
15
ip/iplink.c
|
|
@ -82,11 +82,11 @@ void iplink_usage(void)
|
|||
fprintf(stderr, " [ query_rss { on | off} ]\n");
|
||||
fprintf(stderr, " [ state { auto | enable | disable} ] ]\n");
|
||||
fprintf(stderr, " [ trust { on | off} ] ]\n");
|
||||
fprintf(stderr, " [ master DEVICE ]\n");
|
||||
fprintf(stderr, " [ master DEVICE ][ vrf NAME ]\n");
|
||||
fprintf(stderr, " [ nomaster ]\n");
|
||||
fprintf(stderr, " [ addrgenmode { eui64 | none | stable_secret | random } ]\n");
|
||||
fprintf(stderr, " [ protodown { on | off } ]\n");
|
||||
fprintf(stderr, " ip link show [ DEVICE | group GROUP ] [up] [master DEV] [type TYPE]\n");
|
||||
fprintf(stderr, " ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE]\n");
|
||||
|
||||
if (iplink_have_newlink()) {
|
||||
fprintf(stderr, " ip link help [ TYPE ]\n");
|
||||
|
|
@ -603,6 +603,17 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
|
|||
invarg("Device does not exist\n", *argv);
|
||||
addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
|
||||
&ifindex, 4);
|
||||
} else if (strcmp(*argv, "vrf") == 0) {
|
||||
int ifindex;
|
||||
|
||||
NEXT_ARG();
|
||||
ifindex = ll_name_to_index(*argv);
|
||||
if (!ifindex)
|
||||
invarg("Not a valid VRF name\n", *argv);
|
||||
if (!name_is_vrf(*argv))
|
||||
invarg("Not a valid VRF name\n", *argv);
|
||||
addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
|
||||
&ifindex, sizeof(ifindex));
|
||||
} else if (matches(*argv, "nomaster") == 0) {
|
||||
int ifindex = 0;
|
||||
|
||||
|
|
|
|||
113
ip/iplink_vrf.c
113
ip/iplink_vrf.c
|
|
@ -96,3 +96,116 @@ struct link_util vrf_slave_link_util = {
|
|||
.print_opt = vrf_slave_print_opt,
|
||||
.slave = true,
|
||||
};
|
||||
|
||||
/* returns table id if name is a VRF device */
|
||||
__u32 ipvrf_get_table(const char *name)
|
||||
{
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct ifinfomsg i;
|
||||
char buf[1024];
|
||||
} req = {
|
||||
.n = {
|
||||
.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
|
||||
.nlmsg_flags = NLM_F_REQUEST,
|
||||
.nlmsg_type = RTM_GETLINK,
|
||||
},
|
||||
.i = {
|
||||
.ifi_family = preferred_family,
|
||||
},
|
||||
};
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
char buf[8192];
|
||||
} answer;
|
||||
struct rtattr *tb[IFLA_MAX+1];
|
||||
struct rtattr *li[IFLA_INFO_MAX+1];
|
||||
struct rtattr *vrf_attr[IFLA_VRF_MAX + 1];
|
||||
struct ifinfomsg *ifi;
|
||||
__u32 tb_id = 0;
|
||||
int len;
|
||||
|
||||
addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1);
|
||||
|
||||
if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0)
|
||||
return 0;
|
||||
|
||||
ifi = NLMSG_DATA(&answer.n);
|
||||
len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "BUG: Invalid response to link query.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
|
||||
|
||||
if (!tb[IFLA_LINKINFO])
|
||||
return 0;
|
||||
|
||||
parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
|
||||
|
||||
if (!li[IFLA_INFO_KIND] || !li[IFLA_INFO_DATA])
|
||||
return 0;
|
||||
|
||||
if (strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf"))
|
||||
return 0;
|
||||
|
||||
parse_rtattr_nested(vrf_attr, IFLA_VRF_MAX, li[IFLA_INFO_DATA]);
|
||||
if (vrf_attr[IFLA_VRF_TABLE])
|
||||
tb_id = rta_getattr_u32(vrf_attr[IFLA_VRF_TABLE]);
|
||||
|
||||
if (!tb_id)
|
||||
fprintf(stderr, "BUG: VRF %s is missing table id\n", name);
|
||||
|
||||
return tb_id;
|
||||
}
|
||||
|
||||
bool name_is_vrf(const char *name)
|
||||
{
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct ifinfomsg i;
|
||||
char buf[1024];
|
||||
} req = {
|
||||
.n = {
|
||||
.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
|
||||
.nlmsg_flags = NLM_F_REQUEST,
|
||||
.nlmsg_type = RTM_GETLINK,
|
||||
},
|
||||
.i = {
|
||||
.ifi_family = preferred_family,
|
||||
},
|
||||
};
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
char buf[8192];
|
||||
} answer;
|
||||
struct rtattr *tb[IFLA_MAX+1];
|
||||
struct rtattr *li[IFLA_INFO_MAX+1];
|
||||
struct ifinfomsg *ifi;
|
||||
int len;
|
||||
|
||||
addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, strlen(name) + 1);
|
||||
|
||||
if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0)
|
||||
return false;
|
||||
|
||||
ifi = NLMSG_DATA(&answer.n);
|
||||
len = answer.n.nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "BUG: Invalid response to link query.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
|
||||
|
||||
if (!tb[IFLA_LINKINFO])
|
||||
return false;
|
||||
|
||||
parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
|
||||
|
||||
if (!li[IFLA_INFO_KIND])
|
||||
return false;
|
||||
|
||||
return strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf") == 0;
|
||||
}
|
||||
|
|
|
|||
14
ip/ipneigh.c
14
ip/ipneigh.c
|
|
@ -48,7 +48,8 @@ static void usage(void)
|
|||
{
|
||||
fprintf(stderr, "Usage: ip neigh { add | del | change | replace }\n"
|
||||
" { ADDR [ lladdr LLADDR ] [ nud STATE ] | proxy ADDR } [ dev DEV ]\n");
|
||||
fprintf(stderr, " ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n\n");
|
||||
fprintf(stderr, " ip neigh { show | flush } [ proxy ] [ to PREFIX ] [ dev DEV ] [ nud STATE ]\n");
|
||||
fprintf(stderr, " [ vrf NAME ]\n\n");
|
||||
fprintf(stderr, "STATE := { permanent | noarp | stale | reachable | none |\n"
|
||||
" incomplete | delay | probe | failed }\n");
|
||||
exit(-1);
|
||||
|
|
@ -385,6 +386,17 @@ static int do_show_or_flush(int argc, char **argv, int flush)
|
|||
invarg("Device does not exist\n", *argv);
|
||||
addattr32(&req.n, sizeof(req), NDA_MASTER, ifindex);
|
||||
filter.master = ifindex;
|
||||
} else if (strcmp(*argv, "vrf") == 0) {
|
||||
int ifindex;
|
||||
|
||||
NEXT_ARG();
|
||||
ifindex = ll_name_to_index(*argv);
|
||||
if (!ifindex)
|
||||
invarg("Not a valid VRF name\n", *argv);
|
||||
if (!name_is_vrf(*argv))
|
||||
invarg("Not a valid VRF name\n", *argv);
|
||||
addattr32(&req.n, sizeof(req), NDA_MASTER, ifindex);
|
||||
filter.master = ifindex;
|
||||
} else if (strcmp(*argv, "unused") == 0) {
|
||||
filter.unused_only = 1;
|
||||
} else if (strcmp(*argv, "nud") == 0) {
|
||||
|
|
|
|||
43
ip/iproute.c
43
ip/iproute.c
|
|
@ -67,10 +67,10 @@ static void usage(void)
|
|||
fprintf(stderr, " ip route showdump\n");
|
||||
fprintf(stderr, " ip route get ADDRESS [ from ADDRESS iif STRING ]\n");
|
||||
fprintf(stderr, " [ oif STRING ] [ tos TOS ]\n");
|
||||
fprintf(stderr, " [ mark NUMBER ]\n");
|
||||
fprintf(stderr, " [ mark NUMBER ] [ vrf NAME ]\n");
|
||||
fprintf(stderr, " ip route { add | del | change | append | replace } ROUTE\n");
|
||||
fprintf(stderr, "SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n");
|
||||
fprintf(stderr, " [ table TABLE_ID ] [ proto RTPROTO ]\n");
|
||||
fprintf(stderr, " [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]\n");
|
||||
fprintf(stderr, " [ type TYPE ] [ scope SCOPE ]\n");
|
||||
fprintf(stderr, "ROUTE := NODE_SPEC [ INFO_SPEC ]\n");
|
||||
fprintf(stderr, "NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]\n");
|
||||
|
|
@ -113,7 +113,7 @@ static struct
|
|||
int flushe;
|
||||
int protocol, protocolmask;
|
||||
int scope, scopemask;
|
||||
int type, typemask;
|
||||
__u64 typemask;
|
||||
int tos, tosmask;
|
||||
int iif, iifmask;
|
||||
int oif, oifmask;
|
||||
|
|
@ -178,7 +178,8 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
|
|||
return 0;
|
||||
if ((filter.scope^r->rtm_scope)&filter.scopemask)
|
||||
return 0;
|
||||
if ((filter.type^r->rtm_type)&filter.typemask)
|
||||
|
||||
if (filter.typemask && !(filter.typemask & (1 << r->rtm_type)))
|
||||
return 0;
|
||||
if ((filter.tos^r->rtm_tos)&filter.tosmask)
|
||||
return 0;
|
||||
|
|
@ -365,7 +366,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
|||
|
||||
if (n->nlmsg_type == RTM_DELROUTE)
|
||||
fprintf(fp, "Deleted ");
|
||||
if ((r->rtm_type != RTN_UNICAST || show_details > 0) && !filter.type)
|
||||
if ((r->rtm_type != RTN_UNICAST || show_details > 0) &&
|
||||
(!filter.typemask || (filter.typemask & (1 << r->rtm_type))))
|
||||
fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));
|
||||
|
||||
if (tb[RTA_DST]) {
|
||||
|
|
@ -1136,6 +1138,20 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv)
|
|||
addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
|
||||
}
|
||||
table_ok = 1;
|
||||
} else if (matches(*argv, "vrf") == 0) {
|
||||
__u32 tid;
|
||||
|
||||
NEXT_ARG();
|
||||
tid = ipvrf_get_table(*argv);
|
||||
if (tid == 0)
|
||||
invarg("Invalid VRF\n", *argv);
|
||||
if (tid < 256)
|
||||
req.r.rtm_table = tid;
|
||||
else {
|
||||
req.r.rtm_table = RT_TABLE_UNSPEC;
|
||||
addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
|
||||
}
|
||||
table_ok = 1;
|
||||
} else if (strcmp(*argv, "dev") == 0 ||
|
||||
strcmp(*argv, "oif") == 0) {
|
||||
NEXT_ARG();
|
||||
|
|
@ -1390,6 +1406,15 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
|
|||
}
|
||||
} else
|
||||
filter.tb = tid;
|
||||
} else if (matches(*argv, "vrf") == 0) {
|
||||
__u32 tid;
|
||||
|
||||
NEXT_ARG();
|
||||
tid = ipvrf_get_table(*argv);
|
||||
if (tid == 0)
|
||||
invarg("Invalid VRF\n", *argv);
|
||||
filter.tb = tid;
|
||||
filter.typemask = ~(1 << RTN_LOCAL | 1<<RTN_BROADCAST);
|
||||
} else if (matches(*argv, "cached") == 0 ||
|
||||
matches(*argv, "cloned") == 0) {
|
||||
filter.cloned = 1;
|
||||
|
|
@ -1430,10 +1455,9 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
|
|||
int type;
|
||||
|
||||
NEXT_ARG();
|
||||
filter.typemask = -1;
|
||||
if (rtnl_rtntype_a2n(&type, *argv))
|
||||
invarg("node type value is invalid\n", *argv);
|
||||
filter.type = type;
|
||||
filter.typemask = (1<<type);
|
||||
} else if (strcmp(*argv, "dev") == 0 ||
|
||||
strcmp(*argv, "oif") == 0) {
|
||||
NEXT_ARG();
|
||||
|
|
@ -1677,6 +1701,11 @@ static int iproute_get(int argc, char **argv)
|
|||
req.r.rtm_flags |= RTM_F_NOTIFY;
|
||||
} else if (matches(*argv, "connected") == 0) {
|
||||
connected = 1;
|
||||
} else if (matches(*argv, "vrf") == 0) {
|
||||
NEXT_ARG();
|
||||
if (!name_is_vrf(*argv))
|
||||
invarg("Invalid VRF\n", *argv);
|
||||
odev = *argv;
|
||||
} else {
|
||||
inet_prefix addr;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ ip-address \- protocol address management
|
|||
.IR DEVICE " ] [ "
|
||||
.B type
|
||||
.IR TYPE " ] [ "
|
||||
.B vrf
|
||||
.IR NAME " ] [ "
|
||||
.BR up " ] ]"
|
||||
|
||||
.ti -8
|
||||
|
|
@ -279,6 +281,10 @@ is a usual shell style pattern.
|
|||
.BI master " DEVICE"
|
||||
only list interfaces enslaved to this master device.
|
||||
|
||||
.TP
|
||||
.BI vrf " NAME "
|
||||
only list interfaces enslaved to this vrf.
|
||||
|
||||
.TP
|
||||
.BI type " TYPE"
|
||||
only list interfaces of the given type.
|
||||
|
|
|
|||
|
|
@ -154,6 +154,9 @@ ip-link \- network device configuration
|
|||
.br
|
||||
.RB "[ " nomaster " ]"
|
||||
.br
|
||||
.RB "[ " vrf
|
||||
.IR NAME " ]"
|
||||
.br
|
||||
.RB "[ " addrgenmode " { " eui64 " | " none " | " stable_secret " | " random " } ]"
|
||||
|
||||
|
||||
|
|
@ -167,6 +170,8 @@ ip-link \- network device configuration
|
|||
.IR DEVICE " ] ["
|
||||
.B type
|
||||
.IR TYPE " ]"
|
||||
.B vrf
|
||||
.IR NAME " ]"
|
||||
|
||||
.ti -8
|
||||
.B ip link help
|
||||
|
|
@ -1255,6 +1260,11 @@ only display running interfaces.
|
|||
.I DEVICE
|
||||
specifies the master device which enslaves devices to show.
|
||||
|
||||
.TP
|
||||
.BI vrf " NAME "
|
||||
.I NAME
|
||||
speficies the VRF which enslaves devices to show.
|
||||
|
||||
.TP
|
||||
.BI type " TYPE "
|
||||
.I TYPE
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ ip-neighbour \- neighbour/arp tables management.
|
|||
.B dev
|
||||
.IR DEV " ] [ "
|
||||
.B nud
|
||||
.IR STATE " ]"
|
||||
.IR STATE " ] [ "
|
||||
.B vrf
|
||||
.IR NAME " ] "
|
||||
|
||||
.ti -8
|
||||
.IR STATE " := {"
|
||||
|
|
@ -163,6 +165,10 @@ the prefix selecting the neighbours to list.
|
|||
.BI dev " NAME"
|
||||
only list the neighbours attached to this device.
|
||||
|
||||
.TP
|
||||
.BI vrf " NAME"
|
||||
only list the neighbours for given VRF.
|
||||
|
||||
.TP
|
||||
.BI proxy
|
||||
list neighbour proxies.
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ ip-route \- routing table management
|
|||
.RB " ] [ " oif
|
||||
.IR STRING " ] [ "
|
||||
.B tos
|
||||
.IR TOS " ]"
|
||||
.IR TOS " ] [ "
|
||||
.B vrf
|
||||
.IR NAME " ] "
|
||||
|
||||
.ti -8
|
||||
.BR "ip route" " { " add " | " del " | " change " | " append " | "\
|
||||
|
|
@ -50,6 +52,8 @@ replace " } "
|
|||
.IR PREFIX " ] [ "
|
||||
.B table
|
||||
.IR TABLE_ID " ] [ "
|
||||
.B vrf
|
||||
.IR NAME " ] [ "
|
||||
.B proto
|
||||
.IR RTPROTO " ] [ "
|
||||
.B type
|
||||
|
|
@ -368,6 +372,11 @@ routes, which are put into the
|
|||
.B local
|
||||
table by default.
|
||||
|
||||
.TP
|
||||
.BI vrf " NAME"
|
||||
the vrf name to add this route to. Implicitly means the table
|
||||
associated with the VRF.
|
||||
|
||||
.TP
|
||||
.BI dev " NAME"
|
||||
the output device name.
|
||||
|
|
@ -745,6 +754,10 @@ may either be the ID of a real table or one of the special values:
|
|||
- dump the routing cache.
|
||||
.in -8
|
||||
|
||||
.TP
|
||||
.BI vrf " NAME"
|
||||
show the routes for the table associated with the vrf name
|
||||
|
||||
.TP
|
||||
.B cloned
|
||||
.TP
|
||||
|
|
@ -854,6 +867,10 @@ the device from which this packet is expected to arrive.
|
|||
.BI oif " NAME"
|
||||
force the output device on which this packet will be routed.
|
||||
|
||||
.TP
|
||||
.BI vrf " NAME"
|
||||
force the vrf device on which this packet will be routed.
|
||||
|
||||
.TP
|
||||
.B connected
|
||||
if no source address
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ flower \- flow based traffic control filter
|
|||
.ti -8
|
||||
.IR MATCH " := { "
|
||||
.B indev
|
||||
.IR ifname " | { "
|
||||
.IR ifname " | "
|
||||
.BR skip_sw " | " skip_hw
|
||||
.R " | { "
|
||||
.BR dst_mac " | " src_mac " } "
|
||||
.IR mac_address " | "
|
||||
.BR eth_type " { " ipv4 " | " ipv6 " | "
|
||||
|
|
@ -55,6 +57,13 @@ is the name of an interface which must exist at the time of
|
|||
.B tc
|
||||
invocation.
|
||||
.TP
|
||||
.BI skip_sw
|
||||
Do not process filter by software. If hardware has no offload support for this
|
||||
filter, or TC offload is not enabled for the interface, operation will fail.
|
||||
.TP
|
||||
.BI skip_hw
|
||||
Do not process filter by hardware.
|
||||
.TP
|
||||
.BI dst_mac " mac_address"
|
||||
.TQ
|
||||
.BI src_mac " mac_address"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
static void explain(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: ... flower [ MATCH-LIST ]\n");
|
||||
fprintf(stderr, " [ skip_sw | skip_hw ]\n");
|
||||
fprintf(stderr, " [ action ACTION-SPEC ] [ classid CLASSID ]\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Where: MATCH-LIST := [ MATCH-LIST ] MATCH\n");
|
||||
|
|
@ -167,6 +168,7 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
|
|||
struct rtattr *tail;
|
||||
__be16 eth_type = TC_H_MIN(t->tcm_info);
|
||||
__u8 ip_proto = 0xff;
|
||||
__u32 flags = 0;
|
||||
|
||||
if (handle) {
|
||||
ret = get_u32(&t->tcm_handle, handle, 0);
|
||||
|
|
@ -196,6 +198,10 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
|
|||
return -1;
|
||||
}
|
||||
addattr_l(n, MAX_MSG, TCA_FLOWER_CLASSID, &handle, 4);
|
||||
} else if (matches(*argv, "skip_hw") == 0) {
|
||||
flags |= TCA_CLS_FLAGS_SKIP_HW;
|
||||
} else if (matches(*argv, "skip_sw") == 0) {
|
||||
flags |= TCA_CLS_FLAGS_SKIP_SW;
|
||||
} else if (matches(*argv, "indev") == 0) {
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
|
|
@ -294,6 +300,8 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
|
|||
}
|
||||
|
||||
parse_done:
|
||||
addattr32(n, MAX_MSG, TCA_FLOWER_FLAGS, flags);
|
||||
|
||||
ret = addattr16(n, MAX_MSG, TCA_FLOWER_KEY_ETH_TYPE, eth_type);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Illegal \"eth_type\"(0x%x)\n",
|
||||
|
|
@ -498,6 +506,15 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
|
|||
tb[TCA_FLOWER_KEY_TCP_SRC],
|
||||
tb[TCA_FLOWER_KEY_UDP_SRC]);
|
||||
|
||||
if (tb[TCA_FLOWER_FLAGS]) {
|
||||
__u32 flags = rta_getattr_u32(tb[TCA_FLOWER_FLAGS]);
|
||||
|
||||
if (flags & TCA_CLS_FLAGS_SKIP_HW)
|
||||
fprintf(f, "\n skip_hw");
|
||||
if (flags & TCA_CLS_FLAGS_SKIP_SW)
|
||||
fprintf(f, "\n skip_sw");
|
||||
}
|
||||
|
||||
if (tb[TCA_FLOWER_ACT]) {
|
||||
tc_print_action(f, tb[TCA_FLOWER_ACT]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue