From d792d9c01e60656cbfe1b0f1fd6a9b125f5dab0c Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Sat, 21 Oct 2017 10:53:20 -0700 Subject: [PATCH] BIER - see draft-ietf-bier-mpls-encapsulation-10 - midpoint, head and tail functions - supported payload protocols; IPv4 and IPv6 only. Change-Id: I59d7363bb6fdfdce8e4016a68a9c8f5a5e5791cb Signed-off-by: Neale Ranns --- src/vat/api_format.c | 158 ++++++ src/vnet.am | 34 ++ src/vnet/bier/bier.api | 268 +++++++++ src/vnet/bier/bier_api.c | 690 +++++++++++++++++++++++ src/vnet/bier/bier_bit_string.c | 109 ++++ src/vnet/bier/bier_bit_string.h | 107 ++++ src/vnet/bier/bier_disp_dispatch_node.c | 150 +++++ src/vnet/bier/bier_disp_entry.c | 385 +++++++++++++ src/vnet/bier/bier_disp_entry.h | 81 +++ src/vnet/bier/bier_disp_lookup_node.c | 147 +++++ src/vnet/bier/bier_disp_table.c | 396 +++++++++++++ src/vnet/bier/bier_disp_table.h | 110 ++++ src/vnet/bier/bier_drop.c | 101 ++++ src/vnet/bier/bier_entry.c | 388 +++++++++++++ src/vnet/bier/bier_entry.h | 94 ++++ src/vnet/bier/bier_fmask.c | 527 ++++++++++++++++++ src/vnet/bier/bier_fmask.h | 198 +++++++ src/vnet/bier/bier_fmask_db.c | 161 ++++++ src/vnet/bier/bier_fmask_db.h | 61 ++ src/vnet/bier/bier_hdr_inlines.h | 217 ++++++++ src/vnet/bier/bier_imp.c | 288 ++++++++++ src/vnet/bier/bier_imp.h | 87 +++ src/vnet/bier/bier_imp_node.c | 217 ++++++++ src/vnet/bier/bier_input.c | 175 ++++++ src/vnet/bier/bier_input_error.def | 19 + src/vnet/bier/bier_lookup.c | 367 ++++++++++++ src/vnet/bier/bier_lookup_error.def | 18 + src/vnet/bier/bier_output.c | 195 +++++++ src/vnet/bier/bier_output_error.def | 17 + src/vnet/bier/bier_table.c | 744 +++++++++++++++++++++++++ src/vnet/bier/bier_table.h | 172 ++++++ src/vnet/bier/bier_test.c | 951 ++++++++++++++++++++++++++++++++ src/vnet/bier/bier_types.c | 190 +++++++ src/vnet/bier/bier_types.h | 507 +++++++++++++++++ src/vnet/bier/bier_update.c | 182 ++++++ src/vnet/bier/bier_update.h | 24 + src/vnet/buffer.h | 12 + src/vnet/dpo/dpo.c | 1 + src/vnet/dpo/dpo.h | 12 + src/vnet/dpo/drop_dpo.c | 6 + src/vnet/dpo/load_balance.c | 65 ++- src/vnet/dpo/replicate_dpo.c | 14 +- src/vnet/fib/fib_entry.c | 1 + src/vnet/fib/fib_entry.h | 5 + src/vnet/fib/fib_entry_delegate.c | 1 + src/vnet/fib/fib_entry_src.c | 14 +- src/vnet/fib/fib_entry_src_special.c | 1 + src/vnet/fib/fib_node.h | 4 + src/vnet/fib/fib_path.c | 385 ++++++++++++- src/vnet/fib/fib_path.h | 3 + src/vnet/fib/fib_path_list.c | 5 + src/vnet/fib/fib_table.c | 1 + src/vnet/fib/fib_table.h | 2 +- src/vnet/fib/fib_test.c | 67 ++- src/vnet/fib/fib_test.h | 24 +- src/vnet/fib/fib_types.c | 5 + src/vnet/fib/fib_types.h | 113 ++-- src/vnet/ip/ip.api | 7 +- src/vnet/ip/ip_api.c | 43 +- src/vnet/mfib/mfib_entry.c | 3 +- src/vnet/mpls/mpls.api | 3 +- src/vnet/mpls/mpls_api.c | 2 +- src/vnet/srv6/sr_policy_rewrite.c | 2 +- src/vnet/vnet_all_api_h.h | 1 + src/vpp/api/api.c | 1 + src/vpp/api/vpe.api | 1 + test/patches/scapy-2.3.3/bier.patch | 45 ++ test/patches/scapy-2.3.3/mpls.py.patch | 35 +- test/test_bier.py | 390 +++++++++++++ test/test_ip_mcast.py | 57 +- test/vpp_bier.py | 267 +++++++++ test/vpp_ip_route.py | 28 +- test/vpp_papi_provider.py | 119 ++++ 73 files changed, 10133 insertions(+), 147 deletions(-) create mode 100644 src/vnet/bier/bier.api create mode 100644 src/vnet/bier/bier_api.c create mode 100644 src/vnet/bier/bier_bit_string.c create mode 100644 src/vnet/bier/bier_bit_string.h create mode 100644 src/vnet/bier/bier_disp_dispatch_node.c create mode 100644 src/vnet/bier/bier_disp_entry.c create mode 100644 src/vnet/bier/bier_disp_entry.h create mode 100644 src/vnet/bier/bier_disp_lookup_node.c create mode 100644 src/vnet/bier/bier_disp_table.c create mode 100644 src/vnet/bier/bier_disp_table.h create mode 100644 src/vnet/bier/bier_drop.c create mode 100644 src/vnet/bier/bier_entry.c create mode 100644 src/vnet/bier/bier_entry.h create mode 100644 src/vnet/bier/bier_fmask.c create mode 100644 src/vnet/bier/bier_fmask.h create mode 100644 src/vnet/bier/bier_fmask_db.c create mode 100644 src/vnet/bier/bier_fmask_db.h create mode 100644 src/vnet/bier/bier_hdr_inlines.h create mode 100644 src/vnet/bier/bier_imp.c create mode 100644 src/vnet/bier/bier_imp.h create mode 100644 src/vnet/bier/bier_imp_node.c create mode 100644 src/vnet/bier/bier_input.c create mode 100644 src/vnet/bier/bier_input_error.def create mode 100644 src/vnet/bier/bier_lookup.c create mode 100644 src/vnet/bier/bier_lookup_error.def create mode 100644 src/vnet/bier/bier_output.c create mode 100644 src/vnet/bier/bier_output_error.def create mode 100644 src/vnet/bier/bier_table.c create mode 100644 src/vnet/bier/bier_table.h create mode 100644 src/vnet/bier/bier_test.c create mode 100644 src/vnet/bier/bier_types.c create mode 100644 src/vnet/bier/bier_types.h create mode 100644 src/vnet/bier/bier_update.c create mode 100644 src/vnet/bier/bier_update.h create mode 100644 test/patches/scapy-2.3.3/bier.patch create mode 100644 test/test_bier.py create mode 100644 test/vpp_bier.py diff --git a/src/vat/api_format.c b/src/vat/api_format.c index eee5c743959..c75857bc111 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -5180,6 +5180,8 @@ _(ip_mroute_add_del_reply) \ _(mpls_route_add_del_reply) \ _(mpls_table_add_del_reply) \ _(mpls_ip_bind_unbind_reply) \ +_(bier_route_add_del_reply) \ +_(bier_table_add_del_reply) \ _(proxy_arp_add_del_reply) \ _(proxy_arp_intfc_enable_disable_reply) \ _(sw_interface_set_unnumbered_reply) \ @@ -5383,6 +5385,8 @@ _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \ _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply) \ _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply) \ _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply) \ +_(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply) \ +_(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply) \ _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \ _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \ proxy_arp_intfc_enable_disable_reply) \ @@ -8547,6 +8551,154 @@ api_mpls_ip_bind_unbind (vat_main_t * vam) return ret; } +static int +api_bier_table_add_del (vat_main_t * vam) +{ + unformat_input_t *i = vam->input; + vl_api_bier_table_add_del_t *mp; + u8 is_add = 1; + u32 set = 0, sub_domain = 0, hdr_len = 3; + mpls_label_t local_label = MPLS_LABEL_INVALID; + int ret; + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "sub-domain %d", &sub_domain)) + ; + else if (unformat (i, "set %d", &set)) + ; + else if (unformat (i, "label %d", &local_label)) + ; + else if (unformat (i, "hdr-len %d", &hdr_len)) + ; + else if (unformat (i, "add")) + is_add = 1; + else if (unformat (i, "del")) + is_add = 0; + else + { + clib_warning ("parse error '%U'", format_unformat_error, i); + return -99; + } + } + + if (MPLS_LABEL_INVALID == local_label) + { + errmsg ("missing label\n"); + return -99; + } + + /* Construct the API message */ + M (BIER_TABLE_ADD_DEL, mp); + + mp->bt_is_add = is_add; + mp->bt_label = ntohl (local_label); + mp->bt_tbl_id.bt_set = set; + mp->bt_tbl_id.bt_sub_domain = sub_domain; + mp->bt_tbl_id.bt_hdr_len_id = hdr_len; + + /* send it... */ + S (mp); + + /* Wait for a reply... */ + W (ret); + + return (ret); +} + +static int +api_bier_route_add_del (vat_main_t * vam) +{ + unformat_input_t *i = vam->input; + vl_api_bier_route_add_del_t *mp; + u8 is_add = 1; + u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0; + ip4_address_t v4_next_hop_address; + ip6_address_t v6_next_hop_address; + u8 next_hop_set = 0; + u8 next_hop_proto_is_ip4 = 1; + mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID; + int ret; + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address)) + { + next_hop_proto_is_ip4 = 1; + next_hop_set = 1; + } + else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address)) + { + next_hop_proto_is_ip4 = 0; + next_hop_set = 1; + } + if (unformat (i, "sub-domain %d", &sub_domain)) + ; + else if (unformat (i, "set %d", &set)) + ; + else if (unformat (i, "hdr-len %d", &hdr_len)) + ; + else if (unformat (i, "bp %d", &bp)) + ; + else if (unformat (i, "add")) + is_add = 1; + else if (unformat (i, "del")) + is_add = 0; + else if (unformat (i, "out-label %d", &next_hop_out_label)) + ; + else + { + clib_warning ("parse error '%U'", format_unformat_error, i); + return -99; + } + } + + if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label)) + { + errmsg ("next hop / label set\n"); + return -99; + } + if (0 == bp) + { + errmsg ("bit=position not set\n"); + return -99; + } + + /* Construct the API message */ + M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t)); + + mp->br_is_add = is_add; + mp->br_tbl_id.bt_set = set; + mp->br_tbl_id.bt_sub_domain = sub_domain; + mp->br_tbl_id.bt_hdr_len_id = hdr_len; + mp->br_bp = ntohs (bp); + mp->br_n_paths = 1; + mp->br_paths[0].n_labels = 1; + mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label); + mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1); + + if (next_hop_proto_is_ip4) + { + clib_memcpy (mp->br_paths[0].next_hop, + &v4_next_hop_address, sizeof (v4_next_hop_address)); + } + else + { + clib_memcpy (mp->br_paths[0].next_hop, + &v6_next_hop_address, sizeof (v6_next_hop_address)); + } + + /* send it... */ + S (mp); + + /* Wait for a reply... */ + W (ret); + + return (ret); +} + static int api_proxy_arp_add_del (vat_main_t * vam) { @@ -22238,6 +22390,12 @@ _(mpls_ip_bind_unbind, \ _(mpls_tunnel_add_del, \ " via [table-id ]\n" \ "sw_if_index ] [l2] [del]") \ +_(bier_table_add_del, \ + "