X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fpppoe%2Fpppoe.c;h=1589725eddd4f29be7751d2066657cb09fa267b0;hb=b2c31b685fd2cf28436ca32bc93e23eb24c74878;hp=e5ab5d0c0133dfd3f219e2c6183f7be998034c81;hpb=1855b8e48d95289cc9f0a6e339f2148d64ac705c;p=vpp.git diff --git a/src/plugins/pppoe/pppoe.c b/src/plugins/pppoe/pppoe.c index e5ab5d0c013..1589725eddd 100644 --- a/src/plugins/pppoe/pppoe.c +++ b/src/plugins/pppoe/pppoe.c @@ -37,6 +37,8 @@ pppoe_main_t pppoe_main; +static fib_source_t pppoe_fib_src; + u8 * format_pppoe_session (u8 * s, va_list * args) { @@ -65,14 +67,6 @@ format_pppoe_name (u8 * s, va_list * args) return format (s, "pppoe_session%d", dev_instance); } -static uword -dummy_interface_tx (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - clib_warning ("you shouldn't be here, leaking buffers..."); - return frame->n_vectors; -} - static clib_error_t * pppoe_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags) { @@ -85,9 +79,8 @@ pppoe_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags) /* *INDENT-OFF* */ VNET_DEVICE_CLASS (pppoe_device_class,static) = { - .name = "PPPPOE", + .name = "PPPoE", .format_device_name = format_pppoe_name, - .tx_function = dummy_interface_tx, .admin_up_down_function = pppoe_interface_admin_up_down, }; /* *INDENT-ON* */ @@ -105,23 +98,53 @@ pppoe_build_rewrite (vnet_main_t * vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address) { - int len = sizeof (pppoe_header_t) + sizeof (ethernet_header_t); pppoe_main_t *pem = &pppoe_main; pppoe_session_t *t; + vnet_hw_interface_t *hi; + vnet_sw_interface_t *si; + pppoe_header_t *pppoe; u32 session_id; u8 *rw = 0; session_id = pem->session_index_by_sw_if_index[sw_if_index]; t = pool_elt_at_index (pem->sessions, session_id); + int len = sizeof (pppoe_header_t) + sizeof (ethernet_header_t); + si = vnet_get_sw_interface (vnm, t->encap_if_index); + if (si->type == VNET_SW_INTERFACE_TYPE_SUB) + { + if (si->sub.eth.flags.one_tag == 1) + { + len += sizeof (ethernet_vlan_header_t); + } + } + vec_validate_aligned (rw, len - 1, CLIB_CACHE_LINE_BYTES); ethernet_header_t *eth_hdr = (ethernet_header_t *) rw; - clib_memcpy (eth_hdr->dst_address, t->client_mac, 6); - clib_memcpy (eth_hdr->src_address, t->local_mac, 6); eth_hdr->type = clib_host_to_net_u16 (ETHERNET_TYPE_PPPOE_SESSION); + pppoe = (pppoe_header_t *) (eth_hdr + 1); + + if (si->type == VNET_SW_INTERFACE_TYPE_SUB) + { + if (si->sub.eth.flags.one_tag == 1) + { + eth_hdr->type = clib_host_to_net_u16 (ETHERNET_TYPE_VLAN); + ethernet_vlan_header_t *vlan = + (ethernet_vlan_header_t *) (eth_hdr + 1); + vlan->type = clib_host_to_net_u16 (ETHERNET_TYPE_PPPOE_SESSION); + vlan->priority_cfi_and_id = + clib_host_to_net_u16 (si->sub.eth.outer_vlan_id); + pppoe = (pppoe_header_t *) (vlan + 1); + } + si = vnet_get_sw_interface (vnm, si->sup_sw_if_index); + } + + // set the right mac addresses + hi = vnet_get_hw_interface (vnm, si->hw_if_index); + clib_memcpy (eth_hdr->src_address, hi->hw_address, 6); + clib_memcpy (eth_hdr->dst_address, t->client_mac, 6); - pppoe_header_t *pppoe = (pppoe_header_t *) (eth_hdr + 1); pppoe->ver_type = PPPOE_VER_TYPE; pppoe->code = 0; pppoe->session_id = clib_host_to_net_u16 (t->session_id); @@ -147,22 +170,18 @@ pppoe_build_rewrite (vnet_main_t * vnm, */ static void pppoe_fixup (vlib_main_t * vm, - ip_adjacency_t * adj, vlib_buffer_t * b0, const void *data) + const ip_adjacency_t * adj, vlib_buffer_t * b0, const void *data) { - const pppoe_session_t *t; + //const pppoe_session_t *t; pppoe_header_t *pppoe0; + uword len = (uword) data; /* update the rewrite string */ - pppoe0 = vlib_buffer_get_current (b0) + sizeof (ethernet_header_t); + pppoe0 = vlib_buffer_get_current (b0) + len; pppoe0->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0) - sizeof (pppoe_header_t) - + sizeof (pppoe0->ppp_proto) - - sizeof (ethernet_header_t)); - /* Swap to the the packet's output interface to the encap (not the - * session) interface */ - t = data; - vnet_buffer (b0)->sw_if_index[VLIB_TX] = t->encap_if_index; + + sizeof (pppoe0->ppp_proto) - len); } static void @@ -172,6 +191,7 @@ pppoe_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai) dpo_id_t dpo = DPO_INVALID; ip_adjacency_t *adj; pppoe_session_t *t; + vnet_sw_interface_t *si; u32 session_id; ASSERT (ADJ_INDEX_INVALID != ai); @@ -180,12 +200,23 @@ pppoe_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai) session_id = pem->session_index_by_sw_if_index[sw_if_index]; t = pool_elt_at_index (pem->sessions, session_id); + uword len = sizeof (ethernet_header_t); + + si = vnet_get_sw_interface (vnm, t->encap_if_index); + if (si->type == VNET_SW_INTERFACE_TYPE_SUB) + { + if (si->sub.eth.flags.one_tag == 1) + { + len += sizeof (ethernet_vlan_header_t); + } + } + switch (adj->lookup_next_index) { case IP_LOOKUP_NEXT_ARP: case IP_LOOKUP_NEXT_GLEAN: case IP_LOOKUP_NEXT_BCAST: - adj_nbr_midchain_update_rewrite (ai, pppoe_fixup, t, + adj_nbr_midchain_update_rewrite (ai, pppoe_fixup, (void *) len, ADJ_FLAG_NONE, pppoe_build_rewrite (vnm, sw_if_index, @@ -197,7 +228,7 @@ pppoe_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai) * Construct a partial rewrite from the known ethernet mcast dest MAC * There's no MAC fixup, so the last 2 parameters are 0 */ - adj_mcast_midchain_update_rewrite (ai, pppoe_fixup, t, + adj_mcast_midchain_update_rewrite (ai, pppoe_fixup, (void *) len, ADJ_FLAG_NONE, pppoe_build_rewrite (vnm, sw_if_index, @@ -228,7 +259,7 @@ pppoe_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai) /* *INDENT-OFF* */ VNET_HW_INTERFACE_CLASS (pppoe_hw_class) = { - .name = "PPPPOE", + .name = "PPPoE", .format_header = format_pppoe_header_with_length, .build_rewrite = pppoe_build_rewrite, .update_adjacency = pppoe_update_adj, @@ -273,7 +304,7 @@ int vnet_pppoe_add_del_session cached_key.raw = ~0; cached_result.raw = ~0; /* warning be gone */ - memset (&pfx, 0, sizeof (pfx)); + clib_memset (&pfx, 0, sizeof (pfx)); if (!is_ip6) { @@ -320,7 +351,7 @@ int vnet_pppoe_add_del_session return VNET_API_ERROR_INVALID_DECAP_NEXT; pool_get_aligned (pem->sessions, t, CLIB_CACHE_LINE_BYTES); - memset (t, 0, sizeof (*t)); + clib_memset (t, 0, sizeof (*t)); clib_memcpy (t->local_mac, hi->hw_address, 6); @@ -385,7 +416,7 @@ int vnet_pppoe_add_del_session /* add reverse route for client ip */ fib_table_entry_path_add (a->decap_fib_index, &pfx, - FIB_SOURCE_PLUGIN_HI, FIB_ENTRY_FLAG_NONE, + pppoe_fib_src, FIB_ENTRY_FLAG_NONE, fib_proto_to_dpo (pfx.fp_proto), &pfx.fp_addr, sw_if_index, ~0, 1, NULL, FIB_ROUTE_PATH_FLAG_NONE); @@ -417,7 +448,7 @@ int vnet_pppoe_add_del_session /* delete reverse route for client ip */ fib_table_entry_path_remove (a->decap_fib_index, &pfx, - FIB_SOURCE_PLUGIN_HI, + pppoe_fib_src, fib_proto_to_dpo (pfx.fp_proto), &pfx.fp_addr, sw_if_index, ~0, 1, @@ -455,7 +486,7 @@ pppoe_add_del_session_command_fn (vlib_main_t * vm, clib_error_t *error = NULL; /* Cant "universally zero init" (={0}) due to GCC bug 53119 */ - memset (&client_ip, 0, sizeof client_ip); + clib_memset (&client_ip, 0, sizeof client_ip); /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) @@ -527,7 +558,7 @@ pppoe_add_del_session_command_fn (vlib_main_t * vm, goto done; } - memset (a, 0, sizeof (*a)); + clib_memset (a, 0, sizeof (*a)); a->is_add = is_add; a->is_ip6 = ipv6_set; @@ -569,13 +600,13 @@ done: } /*? - * Add or delete a PPPPOE Session. + * Add or delete a PPPoE Session. * * @cliexpar - * Example of how to create a PPPPOE Session: + * Example of how to create a PPPoE Session: * @cliexcmd{create pppoe session client-ip 10.0.3.1 session-id 13 * client-mac 00:01:02:03:04:05 } - * Example of how to delete a PPPPOE Session: + * Example of how to delete a PPPoE Session: * @cliexcmd{create pppoe session client-ip 10.0.3.1 session-id 13 * client-mac 00:01:02:03:04:05 del } ?*/ @@ -601,20 +632,20 @@ show_pppoe_session_command_fn (vlib_main_t * vm, if (pool_elts (pem->sessions) == 0) vlib_cli_output (vm, "No pppoe sessions configured..."); - pool_foreach (t, pem->sessions, - ({ + pool_foreach (t, pem->sessions) + { vlib_cli_output (vm, "%U",format_pppoe_session, t); - })); + } return 0; } /* *INDENT-ON* */ /*? - * Display all the PPPPOE Session entries. + * Display all the PPPoE Session entries. * * @cliexpar - * Example of how to display the PPPPOE Session entries: + * Example of how to display the PPPoE Session entries: * @cliexstart{show pppoe session} * [0] client-ip 10.0.3.1 session_id 13 encap-if-index 0 decap-vrf-id 13 sw_if_index 5 * local-mac a0:b0:c0:d0:e0:f0 client-mac 00:01:02:03:04:05 @@ -628,69 +659,64 @@ VLIB_CLI_COMMAND (show_pppoe_session_command, static) = { }; /* *INDENT-ON* */ -/** Display the contents of the PPPoE Fib. */ -static clib_error_t * -show_pppoe_fib_command_fn (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) +typedef struct pppoe_show_walk_ctx_t_ { - pppoe_main_t *pem = &pppoe_main; - BVT (clib_bihash) * h = &pem->session_table; - BVT (clib_bihash_bucket) * b; - BVT (clib_bihash_value) * v; - pppoe_entry_key_t key; + vlib_main_t *vm; + u8 first_entry; + u32 total_entries; +} pppoe_show_walk_ctx_t; + +static int +pppoe_show_walk_cb (BVT (clib_bihash_kv) * kvp, void *arg) +{ + pppoe_show_walk_ctx_t *ctx = arg; pppoe_entry_result_t result; - u32 first_entry = 1; - u64 total_entries = 0; - int i, j, k; - u8 *s = 0; + pppoe_entry_key_t key; - for (i = 0; i < h->nbuckets; i++) + if (ctx->first_entry) { - b = &h->buckets[i]; - if (b->offset == 0) - continue; - v = BV (clib_bihash_get_value) (h, b->offset); - for (j = 0; j < (1 << b->log2_pages); j++) - { - for (k = 0; k < BIHASH_KVP_PER_PAGE; k++) - { - if (v->kvp[k].key == ~0ULL && v->kvp[k].value == ~0ULL) - continue; - - if (first_entry) - { - first_entry = 0; - vlib_cli_output (vm, - "%=19s%=12s%=13s%=14s", - "Mac-Address", "session_id", "sw_if_index", - "session_index"); - } + ctx->first_entry = 0; + vlib_cli_output (ctx->vm, + "%=19s%=12s%=13s%=14s", + "Mac-Address", "session_id", "sw_if_index", + "session_index"); + } - key.raw = v->kvp[k].key; - result.raw = v->kvp[k].value; + key.raw = kvp->key; + result.raw = kvp->value; + vlib_cli_output (ctx->vm, + "%=19U%=12d%=13d%=14d", + format_ethernet_address, key.fields.mac, + clib_net_to_host_u16 (key.fields.session_id), + result.fields.sw_if_index == ~0 + ? -1 : result.fields.sw_if_index, + result.fields.session_index == ~0 + ? -1 : result.fields.session_index); + ctx->total_entries++; - vlib_cli_output (vm, - "%=19U%=12d%=13d%=14d", - format_ethernet_address, key.fields.mac, - clib_net_to_host_u16 (key.fields.session_id), - result.fields.sw_if_index == ~0 - ? -1 : result.fields.sw_if_index, - result.fields.session_index == ~0 - ? -1 : result.fields.session_index); - vec_reset_length (s); - total_entries++; - } - v++; - } - } + return (BIHASH_WALK_CONTINUE); +} + +/** Display the contents of the PPPoE Fib. */ +static clib_error_t * +show_pppoe_fib_command_fn (vlib_main_t * vm, + unformat_input_t * input, vlib_cli_command_t * cmd) +{ + pppoe_main_t *pem = &pppoe_main; + pppoe_show_walk_ctx_t ctx = { + .first_entry = 1, + .vm = vm, + }; + + BV (clib_bihash_foreach_key_value_pair) + (&pem->session_table, pppoe_show_walk_cb, &ctx); - if (total_entries == 0) + if (ctx.total_entries == 0) vlib_cli_output (vm, "no pppoe fib entries"); else - vlib_cli_output (vm, "%lld pppoe fib entries", total_entries); + vlib_cli_output (vm, "%lld pppoe fib entries", ctx.total_entries); - vec_free (s); return 0; } @@ -737,6 +763,10 @@ pppoe_init (vlib_main_t * vm) ethernet_register_input_type (vm, ETHERNET_TYPE_PPPOE_DISCOVERY, pppoe_cp_dispatch_node.index); + pppoe_fib_src = fib_source_allocate ("pppoe", + FIB_SOURCE_PRIORITY_HI, + FIB_SOURCE_BH_API); + return 0; } @@ -745,7 +775,7 @@ VLIB_INIT_FUNCTION (pppoe_init); /* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { .version = VPP_BUILD_VER, - .description = "PPPoE", + .description = "PPP over Ethernet (PPPoE)", }; /* *INDENT-ON* */