diff options
author | Benoît Ganne <bganne@cisco.com> | 2019-06-06 17:53:21 +0200 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2019-06-26 11:37:24 +0000 |
commit | c47b97ddacc35cb10e4a2b0dcfff3e690ec5bf76 (patch) | |
tree | 54795991d95324283fff26ba91eda78c2fe64adb | |
parent | ab05508e1eb96749b68de8ccd2f6f88ff3e64fad (diff) |
gbp: enforce same endpoint mac and ip src
During packet classification, make sure packets coming from an EP also
matches this specific EP IP address and vice-versa. This prevents and EP
to send a packet on behalf of another EP.
Type: fix
Change-Id: I30287644ec73b90d9b6913952a82b2baedf6a5ff
Signed-off-by: Benoît Ganne <bganne@cisco.com>
-rw-r--r-- | src/plugins/gbp/gbp_classify_node.c | 21 | ||||
-rw-r--r-- | test/test_gbp.py | 16 |
2 files changed, 28 insertions, 9 deletions
diff --git a/src/plugins/gbp/gbp_classify_node.c b/src/plugins/gbp/gbp_classify_node.c index a2d6d4c47ae..9ad2b06148d 100644 --- a/src/plugins/gbp/gbp_classify_node.c +++ b/src/plugins/gbp/gbp_classify_node.c @@ -359,12 +359,12 @@ gbp_lpm_classify_inline (vlib_main_t * vm, while (n_left_from > 0 && n_left_to_next > 0) { u32 bi0, sw_if_index0, fib_index0, lbi0; + const gbp_endpoint_t *ge0, *ge_lpm0; gbp_lpm_classify_next_t next0; const ethernet_header_t *eh0; const gbp_policy_dpo_t *gpd0; const ip4_address_t *ip4_0; const ip6_address_t *ip6_0; - const gbp_endpoint_t *ge0; const gbp_recirc_t *gr0; const dpo_id_t *dpo0; load_balance_t *lb0; @@ -437,15 +437,15 @@ gbp_lpm_classify_inline (vlib_main_t * vm, if (ip4_0) { - ge0 = gbp_endpoint_find_ip4 (ip4_0, fib_index0); + ge_lpm0 = gbp_endpoint_find_ip4 (ip4_0, fib_index0); } else if (ip6_0) { - ge0 = gbp_endpoint_find_ip6 (ip6_0, fib_index0); + ge_lpm0 = gbp_endpoint_find_ip6 (ip6_0, fib_index0); } else { - ge0 = NULL; + ge_lpm0 = NULL; } next0 = vnet_l2_feature_next @@ -456,9 +456,18 @@ gbp_lpm_classify_inline (vlib_main_t * vm, * if we found the EP by IP lookup, it must be from the EP * not a network behind it */ - if (NULL != ge0) + if (NULL != ge_lpm0) { - sclass0 = ge0->ge_fwd.gef_sclass; + if (PREDICT_FALSE (ge0 != ge_lpm0)) + { + /* an EP spoofing another EP */ + sclass0 = SCLASS_INVALID; + next0 = GPB_LPM_CLASSIFY_DROP; + } + else + { + sclass0 = ge0->ge_fwd.gef_sclass; + } goto trace; } } diff --git a/test/test_gbp.py b/test/test_gbp.py index cc26238276a..ac0fb222633 100644 --- a/test/test_gbp.py +++ b/test/test_gbp.py @@ -3618,6 +3618,16 @@ class TestGBP(VppTestCase): rep.add_vpp_config() # + # EP1 impersonating EP3 is dropped + # + p = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") / + Dot1Q(vlan=100) / + ARP(op="who-has", + psrc="10.0.0.3", pdst="10.0.0.128", + hwsrc=eep1.mac, hwdst="ff:ff:ff:ff:ff:ff")) + self.send_and_assert_no_replies(self.pg0, p) + + # # ARP packet from External EPs are accepted and replied to # p_arp = (Ether(src=eep1.mac, dst="ff:ff:ff:ff:ff:ff") / @@ -3630,11 +3640,11 @@ class TestGBP(VppTestCase): # # ARP packet from host in remote subnet are accepted and replied to # - p_arp = (Ether(src=vlan_102.remote_mac, dst="ff:ff:ff:ff:ff:ff") / + p_arp = (Ether(src=eep3.mac, dst="ff:ff:ff:ff:ff:ff") / Dot1Q(vlan=102) / ARP(op="who-has", - psrc="10.0.0.17", pdst="10.0.0.128", - hwsrc=vlan_102.remote_mac, hwdst="ff:ff:ff:ff:ff:ff")) + psrc=eep3.ip4.address, pdst="10.0.0.128", + hwsrc=eep3.mac, hwdst="ff:ff:ff:ff:ff:ff")) rxs = self.send_and_expect(self.pg0, p_arp * 1, self.pg0) # |