pppoe_main_t pppoe_main;
+static fib_source_t pppoe_fib_src;
+
u8 *
format_pppoe_session (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)
{
/* *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* */
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);
*/
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
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);
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,
* 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,
/* *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,
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)
{
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);
/* 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);
/* 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,
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))
goto done;
}
- memset (a, 0, sizeof (*a));
+ clib_memset (a, 0, sizeof (*a));
a->is_add = is_add;
a->is_ip6 = ipv6_set;
}
/*?
- * 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 }
?*/
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
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;
result.fields.session_index == ~0
? -1 : result.fields.session_index);
ctx->total_entries++;
+
+ return (BIHASH_WALK_CONTINUE);
}
/** Display the contents of the PPPoE Fib. */
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;
}
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
- .description = "PPPoE",
+ .description = "PPP over Ethernet (PPPoE)",
};
/* *INDENT-ON* */