if_me.c (c00bf7307678c1ec7feb5b0c16f0ad888bd8fac6) | if_me.c (6d8fdfa9d5e7d4871c5039b0131829f9cbefeee9) |
---|---|
1/*- 2 * Copyright (c) 2014 Andrey V. Elsukov <ae@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * --- 23 unchanged lines hidden (view full) --- 32#include <sys/kernel.h> 33#include <sys/lock.h> 34#include <sys/libkern.h> 35#include <sys/malloc.h> 36#include <sys/module.h> 37#include <sys/mbuf.h> 38#include <sys/priv.h> 39#include <sys/proc.h> | 1/*- 2 * Copyright (c) 2014 Andrey V. Elsukov <ae@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * --- 23 unchanged lines hidden (view full) --- 32#include <sys/kernel.h> 33#include <sys/lock.h> 34#include <sys/libkern.h> 35#include <sys/malloc.h> 36#include <sys/module.h> 37#include <sys/mbuf.h> 38#include <sys/priv.h> 39#include <sys/proc.h> |
40#include <sys/protosw.h> | |
41#include <sys/rmlock.h> 42#include <sys/socket.h> 43#include <sys/sockio.h> 44#include <sys/sx.h> 45#include <sys/sysctl.h> 46#include <sys/syslog.h> 47#include <sys/systm.h> 48 --- 68 unchanged lines hidden (view full) --- 117static VNET_DEFINE(struct if_clone *, me_cloner); 118#define V_me_cloner VNET(me_cloner) 119 120static void me_qflush(struct ifnet *); 121static int me_transmit(struct ifnet *, struct mbuf *); 122static int me_ioctl(struct ifnet *, u_long, caddr_t); 123static int me_output(struct ifnet *, struct mbuf *, 124 const struct sockaddr *, struct route *); | 40#include <sys/rmlock.h> 41#include <sys/socket.h> 42#include <sys/sockio.h> 43#include <sys/sx.h> 44#include <sys/sysctl.h> 45#include <sys/syslog.h> 46#include <sys/systm.h> 47 --- 68 unchanged lines hidden (view full) --- 116static VNET_DEFINE(struct if_clone *, me_cloner); 117#define V_me_cloner VNET(me_cloner) 118 119static void me_qflush(struct ifnet *); 120static int me_transmit(struct ifnet *, struct mbuf *); 121static int me_ioctl(struct ifnet *, u_long, caddr_t); 122static int me_output(struct ifnet *, struct mbuf *, 123 const struct sockaddr *, struct route *); |
125static int me_input(struct mbuf **, int *, int); | 124static int me_input(struct mbuf *, int, int, void *); |
126 127static int me_set_tunnel(struct ifnet *, struct sockaddr_in *, 128 struct sockaddr_in *); 129static void me_delete_tunnel(struct ifnet *); | 125 126static int me_set_tunnel(struct ifnet *, struct sockaddr_in *, 127 struct sockaddr_in *); 128static void me_delete_tunnel(struct ifnet *); |
129static int me_encapcheck(const struct mbuf *, int, int, void *); |
|
130 | 130 |
131#define ME_MINLEN (sizeof(struct ip) + sizeof(struct mobhdr) -\ 132 sizeof(in_addr_t)) 133static const struct encap_config ipv4_encap_cfg = { 134 .proto = IPPROTO_MOBILE, 135 .min_length = ME_MINLEN, 136 .exact_match = (sizeof(in_addr_t) << 4) + 8, 137 .check = me_encapcheck, 138 .input = me_input 139}; 140 |
|
131SYSCTL_DECL(_net_link); 132static SYSCTL_NODE(_net_link, IFT_TUNNEL, me, CTLFLAG_RW, 0, 133 "Minimal Encapsulation for IP (RFC 2004)"); 134#ifndef MAX_ME_NEST 135#define MAX_ME_NEST 1 136#endif 137 138static VNET_DEFINE(int, max_me_nesting) = MAX_ME_NEST; 139#define V_max_me_nesting VNET(max_me_nesting) 140SYSCTL_INT(_net_link_me, OID_AUTO, max_nesting, CTLFLAG_RW | CTLFLAG_VNET, 141 &VNET_NAME(max_me_nesting), 0, "Max nested tunnels"); 142 | 141SYSCTL_DECL(_net_link); 142static SYSCTL_NODE(_net_link, IFT_TUNNEL, me, CTLFLAG_RW, 0, 143 "Minimal Encapsulation for IP (RFC 2004)"); 144#ifndef MAX_ME_NEST 145#define MAX_ME_NEST 1 146#endif 147 148static VNET_DEFINE(int, max_me_nesting) = MAX_ME_NEST; 149#define V_max_me_nesting VNET(max_me_nesting) 150SYSCTL_INT(_net_link_me, OID_AUTO, max_nesting, CTLFLAG_RW | CTLFLAG_VNET, 151 &VNET_NAME(max_me_nesting), 0, "Max nested tunnels"); 152 |
143extern struct domain inetdomain; 144static const struct protosw in_mobile_protosw = { 145 .pr_type = SOCK_RAW, 146 .pr_domain = &inetdomain, 147 .pr_protocol = IPPROTO_MOBILE, 148 .pr_flags = PR_ATOMIC|PR_ADDR, 149 .pr_input = me_input, 150 .pr_output = rip_output, 151 .pr_ctlinput = rip_ctlinput, 152 .pr_ctloutput = rip_ctloutput, 153 .pr_usrreqs = &rip_usrreqs 154}; 155 | |
156static void 157vnet_me_init(const void *unused __unused) 158{ 159 LIST_INIT(&V_me_softc_list); 160 ME_LIST_LOCK_INIT(); 161 V_me_cloner = if_clone_simple(mename, me_clone_create, 162 me_clone_destroy, 0); 163} --- 165 unchanged lines hidden (view full) --- 329 int ret; 330 331 sc = (struct me_softc *)arg; 332 if ((ME2IFP(sc)->if_flags & IFF_UP) == 0) 333 return (0); 334 335 M_ASSERTPKTHDR(m); 336 | 153static void 154vnet_me_init(const void *unused __unused) 155{ 156 LIST_INIT(&V_me_softc_list); 157 ME_LIST_LOCK_INIT(); 158 V_me_cloner = if_clone_simple(mename, me_clone_create, 159 me_clone_destroy, 0); 160} --- 165 unchanged lines hidden (view full) --- 326 int ret; 327 328 sc = (struct me_softc *)arg; 329 if ((ME2IFP(sc)->if_flags & IFF_UP) == 0) 330 return (0); 331 332 M_ASSERTPKTHDR(m); 333 |
337 if (m->m_pkthdr.len < sizeof(struct ip) + sizeof(struct mobhdr) - 338 sizeof(struct in_addr)) 339 return (0); 340 | |
341 ret = 0; 342 ME_RLOCK(sc); 343 if (ME_READY(sc)) { 344 ip = mtod(m, struct ip *); 345 if (sc->me_src.s_addr == ip->ip_dst.s_addr && 346 sc->me_dst.s_addr == ip->ip_src.s_addr) | 334 ret = 0; 335 ME_RLOCK(sc); 336 if (ME_READY(sc)) { 337 ip = mtod(m, struct ip *); 338 if (sc->me_src.s_addr == ip->ip_dst.s_addr && 339 sc->me_dst.s_addr == ip->ip_src.s_addr) |
347 ret = 32 * 2; | 340 ret = 32 * 2 + 8; |
348 } 349 ME_RUNLOCK(sc); 350 return (ret); 351} 352 353static int 354me_set_tunnel(struct ifnet *ifp, struct sockaddr_in *src, 355 struct sockaddr_in *dst) --- 15 unchanged lines hidden (view full) --- 371 ME_LIST_UNLOCK(); 372 373 ME_WLOCK(sc); 374 sc->me_dst = dst->sin_addr; 375 sc->me_src = src->sin_addr; 376 ME_WUNLOCK(sc); 377 378 if (sc->me_ecookie == NULL) | 341 } 342 ME_RUNLOCK(sc); 343 return (ret); 344} 345 346static int 347me_set_tunnel(struct ifnet *ifp, struct sockaddr_in *src, 348 struct sockaddr_in *dst) --- 15 unchanged lines hidden (view full) --- 364 ME_LIST_UNLOCK(); 365 366 ME_WLOCK(sc); 367 sc->me_dst = dst->sin_addr; 368 sc->me_src = src->sin_addr; 369 ME_WUNLOCK(sc); 370 371 if (sc->me_ecookie == NULL) |
379 sc->me_ecookie = encap_attach_func(AF_INET, IPPROTO_MOBILE, 380 me_encapcheck, &in_mobile_protosw, sc); | 372 sc->me_ecookie = ip_encap_attach(&ipv4_encap_cfg, 373 sc, M_WAITOK); |
381 if (sc->me_ecookie != NULL) { 382 ifp->if_drv_flags |= IFF_DRV_RUNNING; 383 if_link_state_change(ifp, LINK_STATE_UP); 384 } 385 return (0); 386} 387 388static void 389me_delete_tunnel(struct ifnet *ifp) 390{ 391 struct me_softc *sc = ifp->if_softc; 392 393 sx_assert(&me_ioctl_sx, SA_XLOCKED); 394 if (sc->me_ecookie != NULL) | 374 if (sc->me_ecookie != NULL) { 375 ifp->if_drv_flags |= IFF_DRV_RUNNING; 376 if_link_state_change(ifp, LINK_STATE_UP); 377 } 378 return (0); 379} 380 381static void 382me_delete_tunnel(struct ifnet *ifp) 383{ 384 struct me_softc *sc = ifp->if_softc; 385 386 sx_assert(&me_ioctl_sx, SA_XLOCKED); 387 if (sc->me_ecookie != NULL) |
395 encap_detach(sc->me_ecookie); | 388 ip_encap_detach(sc->me_ecookie); |
396 sc->me_ecookie = NULL; 397 ME_WLOCK(sc); 398 sc->me_src.s_addr = 0; 399 sc->me_dst.s_addr = 0; 400 ME_WUNLOCK(sc); 401 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 402 if_link_state_change(ifp, LINK_STATE_DOWN); 403} --- 5 unchanged lines hidden (view full) --- 409 410 while (nwords-- > 0) 411 sum += *p++; 412 sum = (sum >> 16) + (sum & 0xffff); 413 sum += (sum >> 16); 414 return (~sum); 415} 416 | 389 sc->me_ecookie = NULL; 390 ME_WLOCK(sc); 391 sc->me_src.s_addr = 0; 392 sc->me_dst.s_addr = 0; 393 ME_WUNLOCK(sc); 394 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 395 if_link_state_change(ifp, LINK_STATE_DOWN); 396} --- 5 unchanged lines hidden (view full) --- 402 403 while (nwords-- > 0) 404 sum += *p++; 405 sum = (sum >> 16) + (sum & 0xffff); 406 sum += (sum >> 16); 407 return (~sum); 408} 409 |
417int 418me_input(struct mbuf **mp, int *offp, int proto) | 410static int 411me_input(struct mbuf *m, int off, int proto, void *arg) |
419{ | 412{ |
420 struct me_softc *sc; | 413 struct me_softc *sc = arg; |
421 struct mobhdr *mh; 422 struct ifnet *ifp; | 414 struct mobhdr *mh; 415 struct ifnet *ifp; |
423 struct mbuf *m; | |
424 struct ip *ip; 425 int hlen; 426 | 416 struct ip *ip; 417 int hlen; 418 |
427 m = *mp; 428 sc = encap_getarg(m); 429 KASSERT(sc != NULL, ("encap_getarg returned NULL")); 430 | |
431 ifp = ME2IFP(sc); 432 /* checks for short packets */ 433 hlen = sizeof(struct mobhdr); 434 if (m->m_pkthdr.len < sizeof(struct ip) + hlen) 435 hlen -= sizeof(struct in_addr); 436 if (m->m_len < sizeof(struct ip) + hlen) 437 m = m_pullup(m, sizeof(struct ip) + hlen); 438 if (m == NULL) --- 226 unchanged lines hidden --- | 419 ifp = ME2IFP(sc); 420 /* checks for short packets */ 421 hlen = sizeof(struct mobhdr); 422 if (m->m_pkthdr.len < sizeof(struct ip) + hlen) 423 hlen -= sizeof(struct in_addr); 424 if (m->m_len < sizeof(struct ip) + hlen) 425 m = m_pullup(m, sizeof(struct ip) + hlen); 426 if (m == NULL) --- 226 unchanged lines hidden --- |