Improve fabric.p4 with BNG support
Change-Id: I08f8991d8cf432785e0c409354b6301c8983bfb4
diff --git a/pipelines/fabric/src/main/resources/include/bng.p4 b/pipelines/fabric/src/main/resources/include/bng.p4
index 9e56fe4..11e4639 100644
--- a/pipelines/fabric/src/main/resources/include/bng.p4
+++ b/pipelines/fabric/src/main/resources/include/bng.p4
@@ -44,6 +44,7 @@
vlan_id_t s_tag = hdr.vlan_tag.vlan_id;
vlan_id_t c_tag = hdr.inner_vlan_tag.vlan_id;
+ _BOOL drop = _FALSE;
// TABLE: t_line_map
// Maps double VLAN tags to line ID. Line IDs are used to uniquelly identify
// a subscriber.
@@ -107,7 +108,7 @@
fmeta.skip_forwarding = _TRUE;
fmeta.skip_next = _TRUE;
mark_to_drop(smeta);
- c_dropped.count(fmeta.bng.line_id);
+ drop = _TRUE;
}
action term_enabled_v4() {
@@ -158,10 +159,16 @@
if (hdr.ipv4.isValid()) {
t_pppoe_term_v4.apply();
+ if (drop == _TRUE) {
+ c_dropped.count(fmeta.bng.line_id);
+ }
}
#ifdef WITH_IPV6
else if (hdr.ipv6.isValid()) {
t_pppoe_term_v6.apply();
+ if (drop == _TRUE) {
+ c_dropped.count(fmeta.bng.line_id);
+ }
}
#endif // WITH_IPV6
}
@@ -180,6 +187,7 @@
// Downstream line map tables.
// Map IP dest address to line ID and next ID. Setting a next ID here
// allows to skip the fabric.p4 forwarding stage later.
+ _BOOL prio = _FALSE;
@hidden
action set_line(bit<32> line_id) {
@@ -234,13 +242,11 @@
// everything is tagged and metered as best-effort traffic.
action qos_prio() {
- m_prio.execute_meter((bit<32>)fmeta.bng.line_id,
- fmeta.bng.ds_meter_result);
+ prio = _TRUE;
}
action qos_besteff() {
- m_besteff.execute_meter((bit<32>)fmeta.bng.line_id,
- fmeta.bng.ds_meter_result);
+ // no-op
}
table t_qos_v4 {
@@ -283,6 +289,13 @@
// destined to subscribers, e.g. to services in the compute
// nodes.
t_qos_v4.apply();
+ if (prio == _TRUE) {
+ m_prio.execute_meter((bit<32>)fmeta.bng.line_id,
+ fmeta.bng.ds_meter_result);
+ } else {
+ m_besteff.execute_meter((bit<32>)fmeta.bng.line_id,
+ fmeta.bng.ds_meter_result);
+ }
}
}
#ifdef WITH_IPV6
@@ -290,6 +303,13 @@
else if (hdr.ipv6.isValid()) {
if (t_line_map_v6.apply().hit) {
t_qos_v6.apply();
+ if (prio == _TRUE) {
+ m_prio.execute_meter((bit<32>)fmeta.bng.line_id,
+ fmeta.bng.ds_meter_result);
+ } else {
+ m_besteff.execute_meter((bit<32>)fmeta.bng.line_id,
+ fmeta.bng.ds_meter_result);
+ }
}
}
#endif // WITH_IPV6
diff --git a/pipelines/fabric/src/main/resources/include/define.p4 b/pipelines/fabric/src/main/resources/include/define.p4
index 8f70fb4..8058416 100644
--- a/pipelines/fabric/src/main/resources/include/define.p4
+++ b/pipelines/fabric/src/main/resources/include/define.p4
@@ -115,6 +115,7 @@
const bit<16> PPPOE_PROTOCOL_IP4 = 0x0021;
const bit<16> PPPOE_PROTOCOL_IP6 = 0x0057;
+const bit<16> PPPOE_PROTOCOL_MPLS = 0x0281;
const bit<8> PROTO_ICMP = 1;
const bit<8> PROTO_TCP = 6;
diff --git a/pipelines/fabric/src/main/resources/include/parser.p4 b/pipelines/fabric/src/main/resources/include/parser.p4
index e0f9fc5..e234676 100644
--- a/pipelines/fabric/src/main/resources/include/parser.p4
+++ b/pipelines/fabric/src/main/resources/include/parser.p4
@@ -90,6 +90,7 @@
state parse_pppoe {
packet.extract(hdr.pppoe);
transition select(hdr.pppoe.protocol) {
+ PPPOE_PROTOCOL_MPLS: parse_mpls;
PPPOE_PROTOCOL_IP4: parse_ipv4;
#ifdef WITH_IPV6
PPPOE_PROTOCOL_IP6: parse_ipv6;