diff options
Diffstat (limited to 'src/plugins/pppoe/pppoe.c')
-rw-r--r-- | src/plugins/pppoe/pppoe.c | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/src/plugins/pppoe/pppoe.c b/src/plugins/pppoe/pppoe.c index 46faa1f33eb..5ad82694ac1 100644 --- a/src/plugins/pppoe/pppoe.c +++ b/src/plugins/pppoe/pppoe.c @@ -98,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); @@ -142,20 +172,16 @@ static void pppoe_fixup (vlib_main_t * vm, 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 @@ -165,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); @@ -173,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, @@ -190,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, |