> On 23 Mar 2016, at 12:36 AM, Masao Uebayashi <[email protected]> wrote:
>
> On Tue, Mar 22, 2016 at 09:36:18PM +1000, David Gwynne wrote:
>> this basically makes the code use if_get instead of carrying a
>> pointer around. this is as mechanical as i can make it.
>>
>> ok?
>>
>> Index: if_vlan_var.h
>> ===================================================================
>> RCS file: /cvs/src/sys/net/if_vlan_var.h,v
>> retrieving revision 1.33
>> diff -u -p -r1.33 if_vlan_var.h
>> --- if_vlan_var.h 14 Mar 2016 03:48:47 -0000 1.33
>> +++ if_vlan_var.h 22 Mar 2016 11:34:45 -0000
>> @@ -61,9 +61,8 @@ struct vlan_mc_entry {
>>
>> struct ifvlan {
>> struct arpcom ifv_ac; /* make this an interface */
>> - struct ifnet *ifv_p; /* parent interface of this vlan */
>> + unsigned int ifv_p; /* parent interface of this vlan */
>> struct ifv_linkmib {
>> - int ifvm_parent;
>> u_int16_t ifvm_proto; /* encapsulation ethertype */
>> u_int16_t ifvm_tag; /* tag to apply on packets leaving if */
>> u_int16_t ifvm_prio; /* prio to apply on packet leaving if */
>> Index: if_vlan.c
>> ===================================================================
>> RCS file: /cvs/src/sys/net/if_vlan.c,v
>> retrieving revision 1.155
>> diff -u -p -r1.155 if_vlan.c
>> --- if_vlan.c 18 Mar 2016 02:40:04 -0000 1.155
>> +++ if_vlan.c 22 Mar 2016 11:34:45 -0000
>> @@ -235,7 +235,12 @@ vlan_start(struct ifnet *ifp)
>> uint8_t prio;
>>
>> ifv = ifp->if_softc;
>> - ifp0 = ifv->ifv_p;
>> + ifp0 = if_get(ifv->ifv_p);
>> + if (ifp0 == NULL || (ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
>> + (IFF_UP|IFF_RUNNING)) {
>> + ifq_purge(&ifp->if_snd);
>
> You can't dereference ifp if (ifp0 == NULL)?
ifp is a pointer to the vlan interface, and ifp0 is supposed to be its parent.
the vlan interface can exist after its parent is detached.
>
>> + goto leave;
>> + }
>>
>> for (;;) {
>> IFQ_DEQUEUE(&ifp->if_snd, m);
>> @@ -247,12 +252,6 @@ vlan_start(struct ifnet *ifp)
>> bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT);
>> #endif /* NBPFILTER > 0 */
>>
>> - if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
>> - (IFF_UP|IFF_RUNNING)) {
>> - ifp->if_oerrors++;
>> - m_freem(m);
>> - continue;
>> - }
>>
>> /* IEEE 802.1p has prio 0 and 1 swapped */
>> prio = m->m_pkthdr.pf.prio;
>> @@ -290,6 +289,9 @@ vlan_start(struct ifnet *ifp)
>> }
>> ifp->if_opackets++;
>> }
>> +
>> +leave:
>> + if_put(ifp0);
>> }
>>
>> struct mbuf *
>> @@ -358,7 +360,7 @@ vlan_input(struct ifnet *ifp0, struct mb
>>
>> list = &tagh[TAG_HASH(tag)];
>> SRPL_FOREACH(ifv, list, &i, ifv_list) {
>> - if (ifp0 == ifv->ifv_p && tag == ifv->ifv_tag &&
>> + if (ifp0->if_index == ifv->ifv_p && tag == ifv->ifv_tag &&
>> etype == ifv->ifv_type)
>> break;
>> }
>> @@ -417,13 +419,13 @@ vlan_config(struct ifvlan *ifv, struct i
>>
>> if (ifp0->if_type != IFT_ETHER)
>> return EPROTONOSUPPORT;
>> - if (ifv->ifv_p == ifp0 && ifv->ifv_tag == tag) /* noop */
>> + if (ifp0->if_index == ifv->ifv_p && ifv->ifv_tag == tag) /* noop */
>> return (0);
>>
>> /* Remember existing interface flags and reset the interface */
>> flags = ifv->ifv_flags;
>> vlan_unconfig(&ifv->ifv_if, ifp0);
>> - ifv->ifv_p = ifp0;
>> + ifv->ifv_p = ifp0->if_index;
>> ifv->ifv_if.if_baudrate = ifp0->if_baudrate;
>>
>> if (ifp0->if_capabilities & IFCAP_VLAN_MTU) {
>> @@ -509,8 +511,9 @@ vlan_unconfig(struct ifnet *ifp, struct
>> struct ifnet *ifp0;
>>
>> ifv = ifp->if_softc;
>> - if ((ifp0 = ifv->ifv_p) == NULL)
>> - return 0;
>> + ifp0 = if_get(ifv->ifv_p);
>> + if (ifp0 == NULL)
>> + goto disconnect;
>>
>> /* Unset promisc mode on the interface and its parent */
>> if (ifv->ifv_flags & IFVF_PROMISC) {
>> @@ -544,8 +547,9 @@ vlan_unconfig(struct ifnet *ifp, struct
>> */
>> vlan_multi_apply(ifv, ifp0, SIOCDELMULTI);
>>
>> +disconnect:
>> /* Disconnect from parent. */
>> - ifv->ifv_p = NULL;
>> + ifv->ifv_p = 0;
>> ifv->ifv_if.if_mtu = ETHERMTU;
>> ifv->ifv_if.if_hardmtu = ETHERMTU;
>> ifv->ifv_flags = 0;
>
> So you're changing error code path here? I'm not sure this correctness
> but I'd change this separately.
its not really an error path, its cleanup. again, if the parent has detached
then this is where we need to reset the vlan interface state.
>
>> @@ -557,6 +561,8 @@ vlan_unconfig(struct ifnet *ifp, struct
>> bzero(LLADDR(sdl), ETHER_ADDR_LEN);
>> bzero(ifv->ifv_ac.ac_enaddr, ETHER_ADDR_LEN);
>>
>> + if_put(ifp0);
>> +
>> return (0);
>> }
>>
>> @@ -564,12 +570,22 @@ void
>> vlan_vlandev_state(void *v)
>> {
>> struct ifvlan *ifv = v;
>> + struct ifnet *ifp0;
>> + int link_state = LINK_STATE_DOWN;
>> + uint64_t baudrate = 0;
>>
>> - if (ifv->ifv_if.if_link_state == ifv->ifv_p->if_link_state)
>> + ifp0 = if_get(ifv->ifv_p);
>> + if (ifp0 != NULL) {
>> + link_state = ifp0->if_link_state;
>> + baudrate = ifp0->if_baudrate;
>> + }
>> + if_put(ifp0);
>> +
>> + if (ifv->ifv_if.if_link_state == link_state)
>> return;
>>
>> - ifv->ifv_if.if_link_state = ifv->ifv_p->if_link_state;
>> - ifv->ifv_if.if_baudrate = ifv->ifv_p->if_baudrate;
>> + ifv->ifv_if.if_link_state = link_state;
>> + ifv->ifv_if.if_baudrate = baudrate;
>> if_link_state_change(&ifv->ifv_if);
>> }
>>
>
> I don't follow the logic here...
the vlans link state is reported as down unless it is attached to a valid
parent, in which case it shadows the parents state. we dont report changes
unless they're different to the current state.
dlg