def add_vlan_meta(self, next_id, new_vlan_id): next_id_ = stringify(next_id, 4) vlan_id_ = stringify(new_vlan_id, 2) self.send_request_add_entry_to_action( "next.vlan_meta", [self.Exact("fabric_metadata.next_id", next_id_)], "next.set_vlan", [("new_vlan_id", vlan_id_)])
def set_egress_vlan_pop(self, egress_port, vlan_id): egress_port = stringify(egress_port, 2) vlan_id = stringify(vlan_id, 2) self.send_request_add_entry_to_action("egress_next.egress_vlan", [ self.Exact("hdr.vlan_tag.vlan_id", vlan_id), self.Exact("standard_metadata.egress_port", egress_port) ], "egress_next.pop_vlan", [])
def add_forwarding_mpls_entry(self, label, next_id): label_ = stringify(label, 3) next_id_ = stringify(next_id, 4) self.send_request_add_entry_to_action( "forwarding.mpls", [self.Exact("mpls_label", label_)], "forwarding.pop_mpls_and_next", [("next_id", next_id_)])
def add_forwarding_acl_cpu_entry(self, eth_type=None, clone=False): eth_type_ = stringify(eth_type, 2) eth_type_mask = stringify(0xFFFF, 2) action_name = "clone_to_cpu" if clone else "punt_to_cpu" self.send_request_add_entry_to_action( "acl.acl", [self.Ternary("eth_type", eth_type_, eth_type_mask)], "acl." + action_name, [], DEFAULT_PRIORITY)
def setup_int(self): self.send_request_add_entry_to_action( "int_egress.int_prep", None, "int_egress.int_transit", [("switch_id", stringify(1, 4))]) req = self.get_new_write_request() for i in xrange(16): base = "int_set_header_0003_i" mf = self.Exact("hdr.int_header.instruction_mask_0003", stringify(i, 1)) action = "int_metadata_insert." + base + str(i) self.push_update_add_entry_to_action( req, "int_metadata_insert.int_inst_0003", [mf], action, []) self.write_request(req) req = self.get_new_write_request() for i in xrange(16): base = "int_set_header_0407_i" mf = self.Exact("hdr.int_header.instruction_mask_0407", stringify(i, 1)) action = "int_metadata_insert." + base + str(i) self.push_update_add_entry_to_action( req, "int_metadata_insert.int_inst_0407", [mf], action, []) self.write_request(req)
def add_next_multicast(self, next_id, mcast_group_id): next_id_ = stringify(next_id, 4) mcast_group_id_ = stringify(mcast_group_id, 2) self.send_request_add_entry_to_action( "next.multicast", [self.Exact("fabric_metadata.next_id", next_id_)], "next.set_mcast_group", [("gid", mcast_group_id_)])
def add_next_output_simple(self, next_id, egress_port): next_id_ = stringify(next_id, 4) egress_port_ = stringify(egress_port, 2) self.send_request_add_entry_to_action( "next.simple", [self.Exact("next_id", next_id_)], "next.output_simple", [("port_num", egress_port_)])
def add_next_vlan(self, next_id, new_vlan_id): next_id_ = stringify(next_id, 4) vlan_id_ = stringify(new_vlan_id, 2) self.send_request_add_entry_to_action( "next.next_vlan", [self.Exact("next_id", next_id_)], "next.set_vlan", [("vlan_id", vlan_id_)])
def add_forwarding_acl_cpu_entry(self, eth_type=None): eth_type_ = stringify(eth_type, 2) eth_type_mask = stringify(0xFFFF, 2) self.send_request_add_entry_to_action( "forwarding.acl", [self.Ternary("fabric_metadata.original_ether_type", eth_type_, eth_type_mask)], "forwarding.send_to_controller", [], DEFAULT_PRIORITY)
def add_next_hop_L3(self, next_id, egress_port, smac, dmac): next_id_ = stringify(next_id, 4) egress_port_ = stringify(egress_port, 2) smac_ = mac_to_binary(smac) dmac_ = mac_to_binary(dmac) self.send_request_add_entry_to_action( "next.simple", [self.Exact("fabric_metadata.next_id", next_id_)], "next.l3_routing", [("port_num", egress_port_), ("smac", smac_), ("dmac", dmac_)])
def runTest(self): self.setup_int() dport = 5060 # int_type=hop-by-hop int_shim = INT_L45_HEAD(int_type=1, length=4) # ins_cnt: 5 = switch id + ports + q occupancy + ig port + eg port) # max_hop_count: 3 # total_hop_count: 0 # instruction_mask_0003: 0xd = switch id (0), ports (1), q occupancy (3) # instruction_mask_0407: 0xc = ig timestamp (4), eg timestamp (5) int_header = "\x00\x05\x03\x00\xdc\x00\x00\x00" # IP proto (UDP), UDP dport (4096) int_tail = INT_L45_TAIL(next_proto=17, proto_param=dport) payload = "\xab" * 128 inner_udp = UDP(sport=5061, dport=dport, chksum=0) # IP tos is 0x04 to enable INT pkt = Ether(src=self.DMAC_2, dst=self.SWITCH_MAC_2) / \ IP(tos=0x04, src=self.S1U_ENB_IPV4, dst=self.END_POINT_IPV4) / \ inner_udp / \ int_shim / int_header / int_tail / \ payload exp_int_shim = INT_L45_HEAD(int_type=1, length=9) # total_hop_count: 1 exp_int_header = "\x00\x05\x03\x01\xdc\x00\x00\x00" # switch id: 1 exp_int_metadata = "\x00\x00\x00\x01" # ig port: port2, eg port: port2 exp_int_metadata += stringify(self.port2, 2) + stringify(self.port1, 2) # q id: 0, q occupancy: ? exp_int_metadata += "\x00\x00\x00\x00" # ig timestamp: ? # eg timestamp: ? exp_int_metadata += "\x00\x00\x00\x00" * 2 exp_int = exp_int_shim / exp_int_header / exp_int_metadata / int_tail exp_pkt = Ether(src=self.SWITCH_MAC_1, dst=self.DMAC_1) / \ MPLS(label=self.mpls_label, cos=0, s=1, ttl=64) / \ IP(tos=0, id=0x1513, flags=0, frag=0, src=self.S1U_SGW_IPV4, dst=self.S1U_ENB_IPV4) / \ UDP(sport=2152, dport=2152, chksum=0) / \ make_gtp(20 + len(inner_udp) + len(exp_int) + len(payload), 1) / \ IP(tos=0x04, src=self.S1U_ENB_IPV4, dst=self.END_POINT_IPV4, ttl=64) / \ inner_udp / \ exp_int / \ payload # We mask off the timestamps as well as the queue occupancy exp_pkt = Mask(exp_pkt) offset_metadata = 14 + 4 + 20 + 8 + 8 + 20 + 8 + 4 + 8 exp_pkt.set_do_not_care((offset_metadata + 9) * 8, 11 * 8) testutils.send_packet(self, self.port2, str(pkt)) testutils.verify_packet(self, exp_pkt, self.port1)
def add_xconnect(self, next_id, port1, port2): next_id_ = stringify(next_id, 4) port1_ = stringify(port1, 2) port2_ = stringify(port2, 2) for (inport, outport) in ((port1_, port2_), (port2_, port1_)): self.send_request_add_entry_to_action("next.xconnect", [ self.Exact("next_id", next_id_), self.Exact("ig_port", inport) ], "next.output_xconnect", [("port_num", outport)])
def add_next_mpls_routing(self, next_id, egress_port, smac, dmac, label): egress_port_ = stringify(egress_port, 2) smac_ = mac_to_binary(smac) dmac_ = mac_to_binary(dmac) label_ = stringify(label, 3) self.add_next_hashed_indirect_action(next_id, "next.mpls_routing_hashed", [("port_num", egress_port_), ("smac", smac_), ("dmac", dmac_), ("label", label_)])
def set_upstream_line_map(self, s_tag, c_tag, line_id): assert line_id != 0 s_tag_ = stringify(s_tag, 2) # outer c_tag_ = stringify(c_tag, 2) # inner line_id_ = stringify(line_id, 4) # Upstream self.send_request_add_entry_to_action( "bng_ingress.upstream.t_line_map", [self.Exact("s_tag", s_tag_), self.Exact("c_tag", c_tag_)], "bng_ingress.upstream.set_line", [("line_id", line_id_)])
def add_next_hop_mpls_v4(self, next_id, egress_port, smac, dmac, label): next_id_ = stringify(next_id, 4) egress_port_ = stringify(egress_port, 2) smac_ = mac_to_binary(smac) dmac_ = mac_to_binary(dmac) label_ = stringify(label, 3) self.send_request_add_entry_to_action( "next.simple", [self.Exact("fabric_metadata.next_id", next_id_)], "next.mpls_routing_v4", [("port_num", egress_port_), ("smac", smac_), ("dmac", dmac_), ("label", label_)])
def get_int_metadata(self, instructions, switch_id, ig_port, eg_port): int_metadata = "" masked_ins_cnt = len(instructions) if INT_SWITCH_ID in instructions: int_metadata += stringify(switch_id, 4) masked_ins_cnt -= 1 if INT_IG_EG_PORT in instructions: int_metadata += stringify(ig_port, 2) + stringify(eg_port, 2) masked_ins_cnt -= 1 int_metadata += "".join(["\x00\x00\x00\x00"] * masked_ins_cnt) return int_metadata, masked_ins_cnt
def add_bridging_entry(self, vlan_id, eth_dstAddr, eth_dstAddr_mask, next_id): vlan_id_ = stringify(vlan_id, 2) eth_dstAddr_ = mac_to_binary(eth_dstAddr) eth_dstAddr_mask_ = mac_to_binary(eth_dstAddr_mask) next_id_ = stringify(next_id, 4) self.send_request_add_entry_to_action("forwarding.bridging", [ self.Exact("hdr.vlan_tag.vlan_id", vlan_id_), self.Ternary("hdr.ethernet.dst_addr", eth_dstAddr_, eth_dstAddr_mask_) ], "forwarding.set_next_id", [("next_id", next_id_)], DEFAULT_PRIORITY)
def add_bridging_entry(self, vlan_id, eth_dstAddr, eth_dstAddr_mask, next_id): vlan_id_ = stringify(vlan_id, 2) mk = [self.Exact("vlan_id", vlan_id_)] if eth_dstAddr is not None: eth_dstAddr_ = mac_to_binary(eth_dstAddr) eth_dstAddr_mask_ = mac_to_binary(eth_dstAddr_mask) mk.append(self.Ternary("eth_dst", eth_dstAddr_, eth_dstAddr_mask_)) next_id_ = stringify(next_id, 4) self.send_request_add_entry_to_action( "forwarding.bridging", mk, "forwarding.set_next_id_bridging", [("next_id", next_id_)], DEFAULT_PRIORITY)
def set_forwarding_type(self, ingress_port, eth_dstAddr, ethertype=0x800, fwd_type=FORWARDING_TYPE_UNICAST_IPV4): ingress_port_ = stringify(ingress_port, 2) eth_dstAddr_ = mac_to_binary(eth_dstAddr) ethertype_ = stringify(ethertype, 2) fwd_type_ = stringify(fwd_type, 1) self.send_request_add_entry_to_action( "filtering.fwd_classifier", [self.Exact("standard_metadata.ingress_port", ingress_port_), self.Exact("hdr.ethernet.dst_addr", eth_dstAddr_), self.Exact("fabric_metadata.original_ether_type", ethertype_)], "filtering.set_forwarding_type", [("fwd_type", fwd_type_)])
def set_forwarding_type(self, ingress_port, eth_dstAddr, ethertype=ETH_TYPE_IPV4, fwd_type=FORWARDING_TYPE_UNICAST_IPV4): ingress_port_ = stringify(ingress_port, 2) eth_dstAddr_ = mac_to_binary(eth_dstAddr) eth_mask_ = mac_to_binary(MAC_MASK) ethertype_ = stringify(ethertype, 2) fwd_type_ = stringify(fwd_type, 1) self.send_request_add_entry_to_action( "filtering.fwd_classifier", [self.Exact("ig_port", ingress_port_), self.Ternary("eth_dst", eth_dstAddr_, eth_mask_), self.Exact("eth_type", ethertype_)], "filtering.set_forwarding_type", [("fwd_type", fwd_type_)], priority=DEFAULT_PRIORITY)
def add_next_mpls_routing_group(self, next_id, grp_id, next_hops=None): actions = [] if next_hops is not None: for (egress_port, smac, dmac, label) in next_hops: egress_port_ = stringify(egress_port, 2) smac_ = mac_to_binary(smac) dmac_ = mac_to_binary(dmac) label_ = stringify(label, 3) actions.append([ "next.mpls_routing_hashed", [("port_num", egress_port_), ("smac", smac_), ("dmac", dmac_), ("label", label_)] ]) self.add_next_hashed_group_action(next_id, grp_id, actions)
def setup_line_v4(self, s_tag, c_tag, line_id, ipv4_addr, pppoe_session_id, ds_next_id, enabled=True): assert s_tag != 0 assert c_tag != 0 assert line_id != 0 assert pppoe_session_id != 0 c_tag_ = stringify(c_tag, 2) # inner line_id_ = stringify(line_id, 4) ipv4_addr_ = ipv4_to_binary(ipv4_addr) pppoe_session_id_ = stringify(pppoe_session_id, 2) ds_next_id_ = stringify(ds_next_id, 4) # Upstream self.set_upstream_line_map(s_tag=s_tag, c_tag=c_tag, line_id=line_id) if enabled: # Enable upstream termination. self.send_request_add_entry_to_action( "bng_ingress.upstream.t_pppoe_term_v4", [self.Exact("line_id", line_id_), self.Exact("ipv4_src", ipv4_addr_), self.Exact("pppoe_session_id", pppoe_session_id_)], "bng_ingress.upstream.term_enabled_v4", []) # Downstream if enabled: a_name = "set_line_next" a_params = [ ("line_id", line_id_), ("next_id", ds_next_id_), ] else: a_name = "set_line_drop" a_params = [ ("line_id", line_id_) ] self.send_request_add_entry_to_action( "bng_ingress.downstream.t_line_map_v4", [self.Exact("ipv4_dst", ipv4_addr_)], "bng_ingress.downstream." + a_name, a_params) self.send_request_add_entry_to_action( "bng_egress.downstream.t_session_encap", [self.Exact("line_id", line_id_)], "bng_egress.downstream.encap_v4", [ ("c_tag", c_tag_), ("pppoe_session_id", pppoe_session_id_), ])
def set_ingress_port_vlan(self, ingress_port, vlan_valid=False, vlan_id=0, new_vlan_id=0): ingress_port_ = stringify(ingress_port, 2) vlan_valid_ = '\x01' if vlan_valid else '\x00' vlan_id_ = stringify(vlan_id, 2) vlan_id_mask_ = stringify(4095 if vlan_valid else 0, 2) new_vlan_id_ = stringify(new_vlan_id, 2) action_name = "set_vlan" if vlan_valid else "push_internal_vlan" self.send_request_add_entry_to_action( "filtering.ingress_port_vlan", [self.Exact("standard_metadata.ingress_port", ingress_port_), self.Exact("hdr.vlan_tag.is_valid", vlan_valid_), self.Ternary("hdr.vlan_tag.vlan_id", vlan_id_, vlan_id_mask_)], "filtering." + action_name, [("new_vlan_id", new_vlan_id_)], DEFAULT_PRIORITY)
def setUp(self): super(SpgwSimpleTest, self).setUp() self.add_forwarding_unicast_v4_entry(self.S1U_ENB_IPV4, 32, 1) self.add_forwarding_unicast_v4_entry(self.END_POINT_IPV4, 32, 2) self.add_next_hop_L3(1, self.port2, self.SWITCH_MAC_2, self.DMAC_2) self.add_next_hop_L3(2, self.port1, self.SWITCH_MAC_1, self.DMAC_1) req = p4runtime_pb2.WriteRequest() req.device_id = self.device_id s1u_enb_ipv4_ = ipv4_to_binary(self.S1U_ENB_IPV4) s1u_sgw_ipv4_ = ipv4_to_binary(self.S1U_SGW_IPV4) end_point_ipv4_ = ipv4_to_binary(self.END_POINT_IPV4) self.push_update_add_entry_to_action( req, "spgw_ingress.ue_filter_table", [self.Lpm("ipv4.dst_addr", end_point_ipv4_, 32)], "NoAction", []) self.push_update_add_entry_to_action( req, "spgw_ingress.s1u_filter_table", [self.Exact("spgw_meta.s1u_sgw_addr", s1u_sgw_ipv4_)], "NoAction", []) self.push_update_add_entry_to_action( req, "spgw_ingress.dl_sess_lookup", [self.Exact("ipv4.dst_addr", end_point_ipv4_)], "spgw_ingress.set_dl_sess_info", [("teid", stringify(1, 4)), ("s1u_enb_addr", s1u_enb_ipv4_), ("s1u_sgw_addr", s1u_sgw_ipv4_)]) self.write_request(req)
def set_upstream_pppoe_cp_table(self, pppoe_codes=()): for code in pppoe_codes: code_ = stringify(code, 1) self.send_request_add_entry_to_action( "bng_ingress.upstream.t_pppoe_cp", [self.Exact("pppoe_code", code_)], "bng_ingress.upstream.punt_to_cpu", [], DEFAULT_PRIORITY)
def runTest(self): ip_dst_addr = "10.0.0.1" ip_dst_addr_str = ipv4_to_binary(ip_dst_addr) ig_port = self.swports(1) eg_port = self.swports(2) # port is 9-bit in v1model, i.e. 2 bytes eg_port_str = stringify(eg_port, 2) smac = "\xee\xcd\x00\x7e\x70\x00" dmac = "\xee\x30\xca\x9d\x1e\x00" # we do not care about the src mac address or the src IP address pkt = testutils.simple_tcp_packet(eth_dst=smac, ip_dst=ip_dst_addr, ip_ttl=64) # no forwarding entry: packet must be dropped testutils.send_packet(self, ig_port, pkt) testutils.verify_no_other_packets(self) # add a forwarding entry self.send_request_add_entry_to_action( "l3_host_fwd", [self.Exact("hdr.ipv4.dst_addr", ip_dst_addr_str)], "set_nexthop", [("port", eg_port_str), ("smac", smac), ("dmac", dmac)]) # check that the entry is hit and that no other packets are received exp_pkt = testutils.simple_tcp_packet(eth_src=smac, eth_dst=dmac, ip_dst=ip_dst_addr, ip_ttl=63) testutils.send_packet(self, ig_port, pkt) testutils.verify_packets(self, exp_pkt, [eg_port])
def add_next_hashed_indirect_action(self, next_id, action_name, params): next_id_ = stringify(next_id, 4) mbr_id = self.get_next_mbr_id() self.send_request_add_member("next.hashed_selector", mbr_id, action_name, params) self.send_request_add_entry_to_member( "next.hashed", [self.Exact("next_id", next_id_)], mbr_id)
def add_l2_exact_entry(self, eth_dst, out_port): out_port_ = stringify(out_port, 2) eth_dst_ = mac_to_binary(eth_dst) mk = [self.Exact("hdr.ethernet.dst_addr", eth_dst_)] self.send_request_add_entry_to_action("FabricIngress.l2_exact_table", mk, "FabricIngress.set_output_port", [("port_num", out_port_)])
def add_forwarding_unicast_v4_entry(self, ipv4_dstAddr, ipv4_pLen, next_id): ipv4_dstAddr_ = ipv4_to_binary(ipv4_dstAddr) next_id_ = stringify(next_id, 4) self.send_request_add_entry_to_action( "forwarding.unicast_v4", [self.Lpm("hdr.ipv4.dst_addr", ipv4_dstAddr_, ipv4_pLen)], "forwarding.set_next_id", [("next_id", next_id_)])
def set_ingress_port_vlan(self, ingress_port, vlan_valid=False, vlan_id=0, internal_vlan_id=0): ingress_port_ = stringify(ingress_port, 2) vlan_valid_ = '\x01' if vlan_valid else '\x00' vlan_id_ = stringify(vlan_id, 2) vlan_id_mask_ = stringify(4095 if vlan_valid else 0, 2) new_vlan_id_ = stringify(internal_vlan_id, 2) action_name = "permit" if vlan_valid else "permit_with_internal_vlan" action_params = [] if vlan_valid else [("vlan_id", new_vlan_id_)] self.send_request_add_entry_to_action("filtering.ingress_port_vlan", [ self.Exact("ig_port", ingress_port_), self.Exact("vlan_is_valid", vlan_valid_), self.Ternary("vlan_id", vlan_id_, vlan_id_mask_) ], "filtering." + action_name, action_params, DEFAULT_PRIORITY)