mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-27 09:02:06 +00:00
openvswitch: 802.1AD Flow handling, actions, vlan parsing, netlink attributes
Add support for 802.1ad including the ability to push and pop double tagged vlans. Add support for 802.1ad to netlink parsing and flow conversion. Uses double nested encap attributes to represent double tagged vlan. Inner TPID encoded along with ctci in nested attributes. This is based on Thomas F Herbert's original v20 patch. I made some small clean ups and bug fixes. Signed-off-by: Thomas F Herbert <thomasfherbert@gmail.com> Signed-off-by: Eric Garver <e@erig.me> Acked-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
fe19c4f971
commit
018c1dda5f
5 changed files with 282 additions and 124 deletions
|
@ -302,24 +302,57 @@ static bool icmp6hdr_ok(struct sk_buff *skb)
|
|||
sizeof(struct icmp6hdr));
|
||||
}
|
||||
|
||||
static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key)
|
||||
/**
|
||||
* Parse vlan tag from vlan header.
|
||||
* Returns ERROR on memory error.
|
||||
* Returns 0 if it encounters a non-vlan or incomplete packet.
|
||||
* Returns 1 after successfully parsing vlan tag.
|
||||
*/
|
||||
static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh)
|
||||
{
|
||||
struct qtag_prefix {
|
||||
__be16 eth_type; /* ETH_P_8021Q */
|
||||
__be16 tci;
|
||||
};
|
||||
struct qtag_prefix *qp;
|
||||
struct vlan_head *vh = (struct vlan_head *)skb->data;
|
||||
|
||||
if (unlikely(skb->len < sizeof(struct qtag_prefix) + sizeof(__be16)))
|
||||
if (likely(!eth_type_vlan(vh->tpid)))
|
||||
return 0;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, sizeof(struct qtag_prefix) +
|
||||
sizeof(__be16))))
|
||||
if (unlikely(skb->len < sizeof(struct vlan_head) + sizeof(__be16)))
|
||||
return 0;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, sizeof(struct vlan_head) +
|
||||
sizeof(__be16))))
|
||||
return -ENOMEM;
|
||||
|
||||
qp = (struct qtag_prefix *) skb->data;
|
||||
key->eth.tci = qp->tci | htons(VLAN_TAG_PRESENT);
|
||||
__skb_pull(skb, sizeof(struct qtag_prefix));
|
||||
vh = (struct vlan_head *)skb->data;
|
||||
key_vh->tci = vh->tci | htons(VLAN_TAG_PRESENT);
|
||||
key_vh->tpid = vh->tpid;
|
||||
|
||||
__skb_pull(skb, sizeof(struct vlan_head));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key)
|
||||
{
|
||||
int res;
|
||||
|
||||
key->eth.vlan.tci = 0;
|
||||
key->eth.vlan.tpid = 0;
|
||||
key->eth.cvlan.tci = 0;
|
||||
key->eth.cvlan.tpid = 0;
|
||||
|
||||
if (likely(skb_vlan_tag_present(skb))) {
|
||||
key->eth.vlan.tci = htons(skb->vlan_tci);
|
||||
key->eth.vlan.tpid = skb->vlan_proto;
|
||||
} else {
|
||||
/* Parse outer vlan tag in the non-accelerated case. */
|
||||
res = parse_vlan_tag(skb, &key->eth.vlan);
|
||||
if (res <= 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Parse inner vlan tag. */
|
||||
res = parse_vlan_tag(skb, &key->eth.cvlan);
|
||||
if (res <= 0)
|
||||
return res;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -480,12 +513,8 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
|
|||
* update skb->csum here.
|
||||
*/
|
||||
|
||||
key->eth.tci = 0;
|
||||
if (skb_vlan_tag_present(skb))
|
||||
key->eth.tci = htons(skb->vlan_tci);
|
||||
else if (eth->h_proto == htons(ETH_P_8021Q))
|
||||
if (unlikely(parse_vlan(skb, key)))
|
||||
return -ENOMEM;
|
||||
if (unlikely(parse_vlan(skb, key)))
|
||||
return -ENOMEM;
|
||||
|
||||
key->eth.type = parse_ethertype(skb);
|
||||
if (unlikely(key->eth.type == htons(0)))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue