wrong mac address used with carp and unnumbered carpdevs

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

wrong mac address used with carp and unnumbered carpdevs

Henning Brauer-7
so, carp interface with underlaying unnumbered carpdev, i. e.

ifconfig em1 up
ifconfig carp0 carpdev em1 vhid 0 ... 10.0.0.1/24

carp announcements and some stuff like arp goes out with the carp
interface mac address, fine.
however, IP traffic goes out with the carpdev's mac, which is wrong
and leads to problems in places with a strict mac address regime -
exchange points are a typical case.

the culprit is sys/net/if_ethersubr.c ether_output().

The ifp passed to ether_output is (usually) determined by looking up
the route to the destination and grabbing the ifp from it. So in the
numbered carpdev case (em1 10.0.0.x/24, carp 10.0.0.y/32) it'll be the
carpdev (em1 here) right away. In the unnumbered carpdev case, it'll be
the carp interface itself. ether_output has a hack to exchange the carp
ifp with the carpdev's one, to send out the frame on the carpdev and
not the carp if. This little hack is before the src mac address is
determined tho, and that is the bug.

ok?

Index: if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.175
diff -u -p -r1.175 if_ethersubr.c
--- if_ethersubr.c 7 Oct 2014 20:23:32 -0000 1.175
+++ if_ethersubr.c 28 Oct 2014 12:18:36 -0000
@@ -270,6 +270,8 @@ ether_output(struct ifnet *ifp0, struct
  senderr(EBUSY);
 #endif
 
+ esrc = ac->ac_enaddr;
+
 #if NCARP > 0
  if (ifp->if_type == IFT_CARP) {
  ifp = ifp->if_carpdev;
@@ -310,7 +312,6 @@ ether_output(struct ifnet *ifp0, struct
     time_second < rt->rt_rmx.rmx_expire)
  senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
  }
- esrc = ac->ac_enaddr;
  switch (dst->sa_family) {
 
 #ifdef INET


--
Henning Brauer, [hidden email], [hidden email]
BS Web Services GmbH, http://bsws.de, Full-Service ISP
Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed
Henning Brauer Consulting, http://henningbrauer.com/

Reply | Threaded
Open this post in threaded view
|

Re: wrong mac address used with carp and unnumbered carpdevs

David Gwynne-5
ola,

while your explanation is good it still makes my head hurt. i think it makes sense, but i will throw it on a box here to try. we use both numbered and unnumbered carpdevs.

dlg

> On 28 Oct 2014, at 23:56, Henning Brauer <[hidden email]> wrote:
>
> so, carp interface with underlaying unnumbered carpdev, i. e.
>
> ifconfig em1 up
> ifconfig carp0 carpdev em1 vhid 0 ... 10.0.0.1/24
>
> carp announcements and some stuff like arp goes out with the carp
> interface mac address, fine.
> however, IP traffic goes out with the carpdev's mac, which is wrong
> and leads to problems in places with a strict mac address regime -
> exchange points are a typical case.
>
> the culprit is sys/net/if_ethersubr.c ether_output().
>
> The ifp passed to ether_output is (usually) determined by looking up
> the route to the destination and grabbing the ifp from it. So in the
> numbered carpdev case (em1 10.0.0.x/24, carp 10.0.0.y/32) it'll be the
> carpdev (em1 here) right away. In the unnumbered carpdev case, it'll be
> the carp interface itself. ether_output has a hack to exchange the carp
> ifp with the carpdev's one, to send out the frame on the carpdev and
> not the carp if. This little hack is before the src mac address is
> determined tho, and that is the bug.
>
> ok?
>
> Index: if_ethersubr.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_ethersubr.c,v
> retrieving revision 1.175
> diff -u -p -r1.175 if_ethersubr.c
> --- if_ethersubr.c 7 Oct 2014 20:23:32 -0000 1.175
> +++ if_ethersubr.c 28 Oct 2014 12:18:36 -0000
> @@ -270,6 +270,8 @@ ether_output(struct ifnet *ifp0, struct
> senderr(EBUSY);
> #endif
>
> + esrc = ac->ac_enaddr;
> +
> #if NCARP > 0
> if (ifp->if_type == IFT_CARP) {
> ifp = ifp->if_carpdev;
> @@ -310,7 +312,6 @@ ether_output(struct ifnet *ifp0, struct
>    time_second < rt->rt_rmx.rmx_expire)
> senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
> }
> - esrc = ac->ac_enaddr;
> switch (dst->sa_family) {
>
> #ifdef INET
>
>
> --
> Henning Brauer, [hidden email], [hidden email]
> BS Web Services GmbH, http://bsws.de, Full-Service ISP
> Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed
> Henning Brauer Consulting, http://henningbrauer.com/
>