X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fpppoe%2Fpppoe.c;h=5ad82694ac1c73ea11dd847250af71d67c8cabbb;hb=5f7f47ec7ad642c3938376420ef9530176052cd8;hp=823fa1c04a32f6b17fd32827284633db7b2b63f4;hpb=99a3c6c4836c15c2a354cce84aa18a1dabe76c7e;p=vpp.git diff --git a/src/plugins/pppoe/pppoe.c b/src/plugins/pppoe/pppoe.c index 823fa1c04a3..5ad82694ac1 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 } ?*/ @@ -611,10 +642,10 @@ show_pppoe_session_command_fn (vlib_main_t * vm, /* *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 @@ -635,7 +666,7 @@ typedef struct pppoe_show_walk_ctx_t_ u32 total_entries; } pppoe_show_walk_ctx_t; -static void +static int pppoe_show_walk_cb (BVT (clib_bihash_kv) * kvp, void *arg) { pppoe_show_walk_ctx_t *ctx = arg; @@ -663,6 +694,8 @@ pppoe_show_walk_cb (BVT (clib_bihash_kv) * kvp, void *arg) result.fields.session_index == ~0 ? -1 : result.fields.session_index); ctx->total_entries++; + + return (BIHASH_WALK_CONTINUE); } /** Display the contents of the PPPoE Fib. */ @@ -730,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; } @@ -738,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* */