diff options
-rw-r--r-- | src/plugins/gbp/gbp_contract.h | 1 | ||||
-rw-r--r-- | src/plugins/gbp/gbp_policy_dpo.c | 18 | ||||
-rw-r--r-- | src/plugins/gbp/gbp_policy_node.c | 22 | ||||
-rw-r--r-- | test/test_gbp.py | 40 |
4 files changed, 76 insertions, 5 deletions
diff --git a/src/plugins/gbp/gbp_contract.h b/src/plugins/gbp/gbp_contract.h index c6e9721848e..9de52eb9806 100644 --- a/src/plugins/gbp/gbp_contract.h +++ b/src/plugins/gbp/gbp_contract.h @@ -22,6 +22,7 @@ _(ALLOW_NO_SCLASS, "allow-no-sclass") \ _(ALLOW_INTRA, "allow-intra-sclass") \ _(ALLOW_A_BIT, "allow-a-bit-set") \ + _(ALLOW_SCLASS_1, "allow-sclass-1") \ _(ALLOW_CONTRACT, "allow-contract") \ _(DROP_CONTRACT, "drop-contract") \ _(DROP_ETHER_TYPE, "drop-ether-type") \ diff --git a/src/plugins/gbp/gbp_policy_dpo.c b/src/plugins/gbp/gbp_policy_dpo.c index a6194df6836..a7077899fd8 100644 --- a/src/plugins/gbp/gbp_policy_dpo.c +++ b/src/plugins/gbp/gbp_policy_dpo.c @@ -270,12 +270,12 @@ gbp_policy_dpo_inline (vlib_main_t * vm, { gbp_main_t *gm = &gbp_main; u32 n_left_from, next_index, *from, *to_next, thread_index; - u32 n_allow_intra, n_allow_a_bit; + u32 n_allow_intra, n_allow_a_bit, n_allow_sclass_1; gbp_rule_t *gu; from = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; - n_allow_intra = n_allow_a_bit = 0; + n_allow_intra = n_allow_a_bit = n_allow_sclass_1 = 0; thread_index = vm->thread_index; next_index = node->cached_next_index; @@ -343,6 +343,16 @@ gbp_policy_dpo_inline (vlib_main_t * vm, n_allow_intra++; action0 = 0; } + else if (PREDICT_FALSE (key0.gck_src == 1 || key0.gck_dst == 1)) + { + /* + * sclass or dclass 1 allowed + */ + next0 = gpd0->gpd_dpo.dpoi_next_node; + vnet_buffer2 (b0)->gbp.flags |= VXLAN_GBP_GPFLAGS_A; + n_allow_sclass_1++; + action0 = 0; + } else { gci0 = gbp_contract_find (&key0); @@ -449,7 +459,9 @@ gbp_policy_dpo_inline (vlib_main_t * vm, vlib_node_increment_counter (vm, node->node_index, GBP_POLICY_DPO_ERROR_ALLOW_A_BIT, n_allow_a_bit); - + vlib_node_increment_counter (vm, node->node_index, + GBP_POLICY_DPO_ERROR_ALLOW_SCLASS_1, + n_allow_sclass_1); return from_frame->n_vectors; } diff --git a/src/plugins/gbp/gbp_policy_node.c b/src/plugins/gbp/gbp_policy_node.c index 8fe1d7f6c0f..2cffc79cf2d 100644 --- a/src/plugins/gbp/gbp_policy_node.c +++ b/src/plugins/gbp/gbp_policy_node.c @@ -116,13 +116,13 @@ gbp_policy_inline (vlib_main_t * vm, gbp_policy_main_t *gpm = &gbp_policy_main; u32 n_left_from, *from, *to_next; u32 next_index, thread_index; - u32 n_allow_intra, n_allow_a_bit; + u32 n_allow_intra, n_allow_a_bit, n_allow_sclass_1; next_index = 0; n_left_from = frame->n_vectors; from = vlib_frame_vector_args (frame); thread_index = vm->thread_index; - n_allow_intra = n_allow_a_bit = 0; + n_allow_intra = n_allow_a_bit = n_allow_sclass_1 = 0; while (n_left_from > 0) { @@ -216,6 +216,21 @@ gbp_policy_inline (vlib_main_t * vm, vnet_buffer2 (b0)->gbp.flags |= VXLAN_GBP_GPFLAGS_A; n_allow_intra++; } + else if (PREDICT_FALSE (key0.gck_src == 1 || key0.gck_dst == 1)) + { + /* + * sclass or dclass 1 allowed + */ + next0 = + vnet_l2_feature_next (b0, + gpm->l2_output_feat_next + [is_port_based], + (is_port_based ? + L2OUTPUT_FEAT_GBP_POLICY_PORT : + L2OUTPUT_FEAT_GBP_POLICY_MAC)); + vnet_buffer2 (b0)->gbp.flags |= VXLAN_GBP_GPFLAGS_A; + n_allow_sclass_1++; + } else { gci0 = gbp_contract_find (&key0); @@ -377,6 +392,9 @@ gbp_policy_inline (vlib_main_t * vm, GBP_POLICY_ERROR_ALLOW_INTRA, n_allow_intra); vlib_node_increment_counter (vm, node->node_index, GBP_POLICY_ERROR_ALLOW_A_BIT, n_allow_a_bit); + vlib_node_increment_counter (vm, node->node_index, + GBP_POLICY_ERROR_ALLOW_SCLASS_1, + n_allow_sclass_1); return frame->n_vectors; } diff --git a/test/test_gbp.py b/test/test_gbp.py index 73acfdf5346..44a9b396730 100644 --- a/test/test_gbp.py +++ b/test/test_gbp.py @@ -1814,6 +1814,30 @@ class TestGBP(VppTestCase): mac=l['mac'])) # + # repeat in the other EPG + # there's no contract between 220 and 330, but the sclass is set to 1 + # so the packet is cleared for delivery + # + for l in learnt: + # a packet with an sclass from a known EPG + p = (Ether(src=self.pg2.remote_mac, + dst=self.pg2.local_mac) / + IP(src=self.pg2.remote_hosts[1].ip4, + dst=self.pg2.local_ip4) / + UDP(sport=1234, dport=48879) / + VXLAN(vni=99, gpid=1, flags=0x88) / + Ether(src=l['mac'], dst=ep.mac) / + IP(src=l['ip'], dst=ep.ip4.address) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rx = self.send_and_expect(self.pg2, p*65, self.pg0) + + self.assertTrue(find_gbp_endpoint(self, + vx_tun_l2_1.sw_if_index, + mac=l['mac'])) + + # # static EP cannot reach the learnt EPs since there is no contract # only test 1 EP as the others could timeout # @@ -3667,6 +3691,22 @@ class TestGBP(VppTestCase): # # ping from host in remote to local external subnets + # there's no contract for this, but sclass is 1. + # + p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / + IP(src=self.pg7.remote_ip4, dst=self.pg7.local_ip4) / + UDP(sport=1234, dport=48879) / + VXLAN(vni=445, gpid=1, flags=0x88) / + Ether(src=self.pg0.remote_mac, dst=str(self.router_mac)) / + IP(src="10.222.0.1", dst="10.220.0.1") / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rxs = self.send_and_expect(self.pg7, p * 3, self.pg0) + self.assertFalse(find_gbp_endpoint(self, ip="10.222.0.1")) + + # + # ping from host in remote to local external subnets # there's no contract for this, but the A bit is set. # p = (Ether(src=self.pg7.remote_mac, dst=self.pg7.local_mac) / |