@@ -589,6 +589,9 @@ enum {
TCA_FLOWER_KEY_NUM_OF_VLANS, /* u8 */
+ TCA_FLOWER_KEY_PPPOE_SID, /* u16 */
+ TCA_FLOWER_KEY_PPP_PROTO, /* be16 */
+
__TCA_FLOWER_MAX,
};
@@ -40,6 +40,10 @@ flower \- flow based traffic control filter
.IR PRIORITY " | "
.BR cvlan_ethtype " { " ipv4 " | " ipv6 " | "
.IR ETH_TYPE " } | "
+.B pppoe_sid
+.IR PSID " | "
+.BR ppp_proto " { " ip " | " ipv6 " | " mpls_uc " | " mpls_mc " | "
+.IR PPP_PROTO " } | "
.B mpls
.IR LSE_LIST " | "
.B mpls_label
@@ -202,7 +206,18 @@ Match on QinQ layer three protocol.
may be either
.BR ipv4 ", " ipv6
or an unsigned 16bit value in hexadecimal format.
-
+.TP
+.BI pppoe_sid " PSID"
+Match on PPPoE session id.
+.I PSID
+is an unsigned 16bit value in decimal format.
+.TP
+.BI ppp_proto " PPP_PROTO"
+Match on PPP layer three protocol.
+.I PPP_PROTO
+may be either
+.BR ip ", " ipv6 ", " mpls_uc ", " mpls_mc
+or an unsigned 16bit value in hexadecimal format.
.TP
.BI mpls " LSE_LIST"
Match on the MPLS label stack.
@@ -20,6 +20,7 @@
#include <linux/ip.h>
#include <linux/tc_act/tc_vlan.h>
#include <linux/mpls.h>
+#include <linux/ppp_defs.h>
#include "utils.h"
#include "tc_util.h"
@@ -1887,6 +1888,43 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
fprintf(stderr, "Illegal \"arp_sha\"\n");
return -1;
}
+
+ } else if (!strcmp(*argv, "pppoe_sid")) {
+ __be16 sid;
+
+ NEXT_ARG();
+ if (eth_type != htons(ETH_P_PPP_SES)) {
+ fprintf(stderr,
+ "Can't set \"pppoe_sid\" if ethertype isn't PPPoE session\n");
+ return -1;
+ }
+ ret = get_be16(&sid, *argv, 10);
+ if (ret < 0 || sid == 0xffff) {
+ fprintf(stderr, "Illegal \"pppoe_sid\"\n");
+ return -1;
+ }
+ addattr16(n, MAX_MSG, TCA_FLOWER_KEY_PPPOE_SID, sid);
+ } else if (!strcmp(*argv, "ppp_proto")) {
+ __be16 proto;
+
+ NEXT_ARG();
+ if (eth_type != htons(ETH_P_PPP_SES)) {
+ fprintf(stderr,
+ "Can't set \"ppp_proto\" if ethertype isn't PPPoE session\n");
+ return -1;
+ }
+ if (ppp_proto_a2n(&proto, *argv))
+ invarg("invalid ppp_proto", *argv);
+ /* get new ethtype for later parsing */
+ if (proto == htons(PPP_IP))
+ eth_type = htons(ETH_P_IP);
+ else if (proto == htons(PPP_IPV6))
+ eth_type = htons(ETH_P_IPV6);
+ else if (proto == htons(PPP_MPLS_UC))
+ eth_type = htons(ETH_P_MPLS_UC);
+ else if (proto == htons(PPP_MPLS_MC))
+ eth_type = htons(ETH_P_MPLS_MC);
+ addattr16(n, MAX_MSG, TCA_FLOWER_KEY_PPP_PROTO, proto);
} else if (matches(*argv, "enc_dst_ip") == 0) {
NEXT_ARG();
ret = flower_parse_ip_addr(*argv, 0,
@@ -2851,6 +2889,24 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
flower_print_eth_addr("arp_tha", tb[TCA_FLOWER_KEY_ARP_THA],
tb[TCA_FLOWER_KEY_ARP_THA_MASK]);
+ if (tb[TCA_FLOWER_KEY_PPPOE_SID]) {
+ struct rtattr *attr = tb[TCA_FLOWER_KEY_PPPOE_SID];
+
+ print_nl();
+ print_uint(PRINT_ANY, "pppoe_sid", " pppoe_sid %u",
+ rta_getattr_be16(attr));
+ }
+
+ if (tb[TCA_FLOWER_KEY_PPP_PROTO]) {
+ SPRINT_BUF(buf);
+ struct rtattr *attr = tb[TCA_FLOWER_KEY_PPP_PROTO];
+
+ print_nl();
+ print_string(PRINT_ANY, "ppp_proto", " ppp_proto %s",
+ ppp_proto_n2a(rta_getattr_u16(attr),
+ buf, sizeof(buf)));
+ }
+
flower_print_ip_addr("enc_dst_ip",
tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK] ?
htons(ETH_P_IP) : htons(ETH_P_IPV6),
Introduce PPPoE specific fields in tc-flower: - session id (16 bits) - ppp protocol (16 bits) Those fields can be provided only when protocol was set to ETH_P_PPP_SES. ppp_proto works similar to vlan_ethtype, i.e. ppp_proto overwrites eth_type. Thanks to that, fields from encapsulated protocols (such as src_ip) can be specified. e.g. # tc filter add dev ens6f0 ingress prio 1 protocol ppp_ses \ flower \ pppoe_sid 1234 \ ppp_proto ip \ dst_ip 127.0.0.1 \ src_ip 127.0.0.2 \ action drop Vlan and cvlan is also supported, in this case cvlan_ethtype or vlan_ethtype has to be set to ETH_P_PPP_SES. e.g. # tc filter add dev ens6f0 ingress prio 1 protocol 802.1Q \ flower \ vlan_id 2 \ vlan_ethtype ppp_ses \ pppoe_sid 1234 \ ppp_proto ip \ dst_ip 127.0.0.1 \ src_ip 127.0.0.2 \ action drop Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com> --- include/uapi/linux/pkt_cls.h | 3 ++ man/man8/tc-flower.8 | 17 ++++++++++- tc/f_flower.c | 56 ++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-)