Skip to content

Commit

Permalink
Add the ability to look up the 3b PCP of a VLAN interface. Use it in
Browse files Browse the repository at this point in the history
toe_l2_resolve to fill up the complete vtag and not just the vid.

Reviewed by:	kib@
MFC after:	1 week
Sponsored by:	Chelsio Communications
Differential Revision:	https://reviews.freebsd.org/D16752
  • Loading branch information
np-2020 committed Aug 16, 2018
1 parent beac22c commit 06d6f82
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
1 change: 1 addition & 0 deletions sys/net/if.c
Expand Up @@ -2298,6 +2298,7 @@ void (*vlan_trunk_cap_p)(struct ifnet *); /* XXX: private from if_vlan */
struct ifnet *(*vlan_trunkdev_p)(struct ifnet *);
struct ifnet *(*vlan_devat_p)(struct ifnet *, uint16_t);
int (*vlan_tag_p)(struct ifnet *, uint16_t *);
int (*vlan_pcp_p)(struct ifnet *, uint16_t *);
int (*vlan_setcookie_p)(struct ifnet *, void *);
void *(*vlan_cookie_p)(struct ifnet *);

Expand Down
13 changes: 13 additions & 0 deletions sys/net/if_vlan.c
Expand Up @@ -758,6 +758,18 @@ vlan_tag(struct ifnet *ifp, uint16_t *vidp)
return (0);
}

static int
vlan_pcp(struct ifnet *ifp, uint16_t *pcpp)
{
struct ifvlan *ifv;

if (ifp->if_type != IFT_L2VLAN)
return (EINVAL);
ifv = ifp->if_softc;
*pcpp = ifv->ifv_pcp;
return (0);
}

/*
* Return a driver specific cookie for this interface. Synchronization
* with setcookie must be provided by the driver.
Expand Down Expand Up @@ -861,6 +873,7 @@ vlan_modevent(module_t mod, int type, void *data)
vlan_cookie_p = vlan_cookie;
vlan_setcookie_p = vlan_setcookie;
vlan_tag_p = vlan_tag;
vlan_pcp_p = vlan_pcp;
vlan_devat_p = vlan_devat;
#ifndef VIMAGE
vlan_cloner = if_clone_advanced(vlanname, 0, vlan_clone_match,
Expand Down
3 changes: 3 additions & 0 deletions sys/net/if_vlan_var.h
Expand Up @@ -132,6 +132,8 @@ struct vlanreq {
((_ifp)->if_type == IFT_L2VLAN ? (*vlan_trunkdev_p)((_ifp)) : NULL)
#define VLAN_TAG(_ifp, _vid) \
((_ifp)->if_type == IFT_L2VLAN ? (*vlan_tag_p)((_ifp), (_vid)) : EINVAL)
#define VLAN_PCP(_ifp, _pcp) \
((_ifp)->if_type == IFT_L2VLAN ? (*vlan_pcp_p)((_ifp), (_pcp)) : EINVAL)
#define VLAN_COOKIE(_ifp) \
((_ifp)->if_type == IFT_L2VLAN ? (*vlan_cookie_p)((_ifp)) : NULL)
#define VLAN_SETCOOKIE(_ifp, _cookie) \
Expand All @@ -144,6 +146,7 @@ extern void (*vlan_trunk_cap_p)(struct ifnet *);
extern struct ifnet *(*vlan_trunkdev_p)(struct ifnet *);
extern struct ifnet *(*vlan_devat_p)(struct ifnet *, uint16_t);
extern int (*vlan_tag_p)(struct ifnet *, uint16_t *);
extern int (*vlan_pcp_p)(struct ifnet *, uint16_t *);
extern int (*vlan_setcookie_p)(struct ifnet *, void *);
extern void *(*vlan_cookie_p)(struct ifnet *);

Expand Down
27 changes: 17 additions & 10 deletions sys/netinet/toecore.c
Expand Up @@ -400,7 +400,7 @@ toe_lle_event(void *arg __unused, struct llentry *lle, int evt)
struct ifnet *ifp;
struct sockaddr *sa;
uint8_t *lladdr;
uint16_t vtag;
uint16_t vid, pcp;
int family;
struct sockaddr_in6 sin6;

Expand All @@ -425,7 +425,8 @@ toe_lle_event(void *arg __unused, struct llentry *lle, int evt)
sa = (struct sockaddr *)&sin6;
lltable_fill_sa_entry(lle, sa);

vtag = 0xfff;
vid = 0xfff;
pcp = 0;
if (evt != LLENTRY_RESOLVED) {

/*
Expand All @@ -440,12 +441,11 @@ toe_lle_event(void *arg __unused, struct llentry *lle, int evt)
("%s: %p resolved but not valid?", __func__, lle));

lladdr = (uint8_t *)lle->ll_addr;
#ifdef VLAN_TAG
VLAN_TAG(ifp, &vtag);
#endif
VLAN_TAG(ifp, &vid);
VLAN_PCP(ifp, &pcp);
}

tod->tod_l2_update(tod, ifp, sa, lladdr, vtag);
tod->tod_l2_update(tod, ifp, sa, lladdr, EVL_MAKETAG(vid, pcp, 0));
}

/*
Expand All @@ -458,6 +458,7 @@ toe_l2_resolve(struct toedev *tod, struct ifnet *ifp, struct sockaddr *sa,
uint8_t *lladdr, uint16_t *vtag)
{
int rc;
uint16_t vid, pcp;

switch (sa->sa_family) {
#ifdef INET
Expand All @@ -475,10 +476,16 @@ toe_l2_resolve(struct toedev *tod, struct ifnet *ifp, struct sockaddr *sa,
}

if (rc == 0) {
#ifdef VLAN_TAG
if (VLAN_TAG(ifp, vtag) != 0)
#endif
*vtag = 0xfff;
vid = 0xfff;
pcp = 0;
if (ifp->if_type == IFT_L2VLAN) {
VLAN_TAG(ifp, &vid);
VLAN_PCP(ifp, &pcp);
} else if (ifp->if_pcp != IFNET_PCP_NONE) {
vid = 0;
pcp = ifp->if_pcp;
}
*vtag = EVL_MAKETAG(vid, pcp, 0);
}

return (rc);
Expand Down

0 comments on commit 06d6f82

Please sign in to comment.