2005-01-07 01:45:51 +00:00
|
|
|
/*-
|
2017-11-20 19:43:44 +00:00
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
*
|
1994-05-24 10:09:53 +00:00
|
|
|
* Copyright (c) 1985, 1986, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2017-02-28 23:42:47 +00:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
1994-05-24 10:09:53 +00:00
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
1995-09-21 17:50:45 +00:00
|
|
|
* @(#)in_var.h 8.2 (Berkeley) 1/9/95
|
1999-08-28 01:08:13 +00:00
|
|
|
* $FreeBSD$
|
1994-05-24 10:09:53 +00:00
|
|
|
*/
|
|
|
|
|
1994-08-21 05:27:42 +00:00
|
|
|
#ifndef _NETINET_IN_VAR_H_
|
|
|
|
#define _NETINET_IN_VAR_H_
|
|
|
|
|
2015-02-19 23:59:27 +00:00
|
|
|
/*
|
|
|
|
* Argument structure for SIOCAIFADDR.
|
|
|
|
*/
|
|
|
|
struct in_aliasreq {
|
|
|
|
char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
|
|
|
struct sockaddr_in ifra_addr;
|
|
|
|
struct sockaddr_in ifra_broadaddr;
|
|
|
|
#define ifra_dstaddr ifra_broadaddr
|
|
|
|
struct sockaddr_in ifra_mask;
|
|
|
|
int ifra_vhid;
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef _KERNEL
|
1995-03-23 18:14:41 +00:00
|
|
|
#include <sys/queue.h>
|
2001-09-29 04:34:11 +00:00
|
|
|
#include <sys/fnv_hash.h>
|
2009-03-09 17:53:05 +00:00
|
|
|
#include <sys/tree.h>
|
|
|
|
|
2015-02-19 22:35:23 +00:00
|
|
|
struct igmp_ifsoftc;
|
2009-03-09 17:53:05 +00:00
|
|
|
struct in_multi;
|
|
|
|
struct lltable;
|
2018-05-02 19:36:29 +00:00
|
|
|
SLIST_HEAD(in_multi_head, in_multi);
|
2009-03-09 17:53:05 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* IPv4 per-interface state.
|
|
|
|
*/
|
|
|
|
struct in_ifinfo {
|
|
|
|
struct lltable *ii_llt; /* ARP state */
|
2015-02-19 22:35:23 +00:00
|
|
|
struct igmp_ifsoftc *ii_igmp; /* IGMP state */
|
2009-03-09 17:53:05 +00:00
|
|
|
struct in_multi *ii_allhosts; /* 224.0.0.1 membership */
|
|
|
|
};
|
1995-03-23 18:14:41 +00:00
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
/*
|
|
|
|
* Interface address, Internet version. One of these structures
|
1997-01-13 21:26:53 +00:00
|
|
|
* is allocated for each Internet address on an interface.
|
1994-05-24 10:09:53 +00:00
|
|
|
* The ifaddr structure contains the protocol-independent part
|
|
|
|
* of the structure and is assumed to be first.
|
|
|
|
*/
|
|
|
|
struct in_ifaddr {
|
|
|
|
struct ifaddr ia_ifa; /* protocol-independent info */
|
|
|
|
#define ia_ifp ia_ifa.ifa_ifp
|
|
|
|
#define ia_flags ia_ifa.ifa_flags
|
2011-10-15 16:28:06 +00:00
|
|
|
/* ia_subnet{,mask} in host order */
|
|
|
|
u_long ia_subnet; /* subnet address */
|
|
|
|
u_long ia_subnetmask; /* mask of subnet */
|
2021-10-10 10:02:26 -07:00
|
|
|
CK_LIST_ENTRY(in_ifaddr) ia_hash; /* hash of internet addresses */
|
2018-05-18 20:13:34 +00:00
|
|
|
CK_STAILQ_ENTRY(in_ifaddr) ia_link; /* list of internet addresses */
|
1994-05-24 10:09:53 +00:00
|
|
|
struct sockaddr_in ia_addr; /* reserve space for interface name */
|
|
|
|
struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
|
|
|
|
#define ia_broadaddr ia_dstaddr
|
|
|
|
struct sockaddr_in ia_sockmask; /* reserve space for general netmask */
|
Add GARP retransmit capability
A single gratuitous ARP (GARP) is always transmitted when an IPv4
address is added to an interface, and that is usually sufficient.
However, in some circumstances, such as when a shared address is
passed between cluster nodes, this single GARP may occasionally be
dropped or lost. This can lead to neighbors on the network link
working with a stale ARP cache and sending packets destined for
that address to the node that previously owned the address, which
may not respond.
To avoid this situation, GARP retransmissions can be enabled by setting
the net.link.ether.inet.garp_rexmit_count sysctl to a value greater
than zero. The setting represents the maximum number of retransmissions.
The interval between retransmissions is calculated using an exponential
backoff algorithm, doubling each time, so the retransmission intervals
are: {1, 2, 4, 8, 16, ...} (seconds).
Due to the exponential backoff algorithm used for the interval
between GARP retransmissions, the maximum number of retransmissions
is limited to 16 for sanity. This limit corresponds to a maximum
interval between retransmissions of 2^16 seconds ~= 18 hours.
Increasing this limit is possible, but sending out GARPs spaced
days apart would be of little use.
Submitted by: David A. Bright <david.a.bright@dell.com>
MFC after: 1 month
Relnotes: yes
Sponsored by: Dell EMC
Differential Revision: https://reviews.freebsd.org/D7695
2016-10-02 01:42:45 +00:00
|
|
|
struct callout ia_garp_timer; /* timer for retransmitting GARPs */
|
|
|
|
int ia_garp_count; /* count of retransmitted GARPs */
|
1994-05-24 10:09:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Given a pointer to an in_ifaddr (ifaddr),
|
|
|
|
* return a pointer to the addr as a sockaddr_in.
|
|
|
|
*/
|
1994-10-25 22:13:32 +00:00
|
|
|
#define IA_SIN(ia) (&(((struct in_ifaddr *)(ia))->ia_addr))
|
|
|
|
#define IA_DSTSIN(ia) (&(((struct in_ifaddr *)(ia))->ia_dstaddr))
|
2012-01-08 17:20:29 +00:00
|
|
|
#define IA_MASKSIN(ia) (&(((struct in_ifaddr *)(ia))->ia_sockmask))
|
1994-05-24 10:09:53 +00:00
|
|
|
|
|
|
|
#define IN_LNAOF(in, ifa) \
|
|
|
|
((ntohl((in).s_addr) & ~((struct in_ifaddr *)(ifa)->ia_subnetmask))
|
1995-05-30 08:16:23 +00:00
|
|
|
|
1995-03-16 18:17:34 +00:00
|
|
|
extern u_char inetctlerrmap[];
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2009-04-15 20:49:59 +00:00
|
|
|
#define LLTABLE(ifp) \
|
|
|
|
((struct in_ifinfo *)(ifp)->if_afdata[AF_INET])->ii_llt
|
2004-08-16 18:32:07 +00:00
|
|
|
/*
|
2001-09-29 04:34:11 +00:00
|
|
|
* Hash table for IP addresses.
|
|
|
|
*/
|
2018-05-18 20:13:34 +00:00
|
|
|
CK_STAILQ_HEAD(in_ifaddrhead, in_ifaddr);
|
2021-10-10 10:02:26 -07:00
|
|
|
CK_LIST_HEAD(in_ifaddrhashhead, in_ifaddr);
|
Build on Jeff Roberson's linker-set based dynamic per-CPU allocator
(DPCPU), as suggested by Peter Wemm, and implement a new per-virtual
network stack memory allocator. Modify vnet to use the allocator
instead of monolithic global container structures (vinet, ...). This
change solves many binary compatibility problems associated with
VIMAGE, and restores ELF symbols for virtualized global variables.
Each virtualized global variable exists as a "reference copy", and also
once per virtual network stack. Virtualized global variables are
tagged at compile-time, placing the in a special linker set, which is
loaded into a contiguous region of kernel memory. Virtualized global
variables in the base kernel are linked as normal, but those in modules
are copied and relocated to a reserved portion of the kernel's vnet
region with the help of a the kernel linker.
Virtualized global variables exist in per-vnet memory set up when the
network stack instance is created, and are initialized statically from
the reference copy. Run-time access occurs via an accessor macro, which
converts from the current vnet and requested symbol to a per-vnet
address. When "options VIMAGE" is not compiled into the kernel, normal
global ELF symbols will be used instead and indirection is avoided.
This change restores static initialization for network stack global
variables, restores support for non-global symbols and types, eliminates
the need for many subsystem constructors, eliminates large per-subsystem
structures that caused many binary compatibility issues both for
monitoring applications (netstat) and kernel modules, removes the
per-function INIT_VNET_*() macros throughout the stack, eliminates the
need for vnet_symmap ksym(2) munging, and eliminates duplicate
definitions of virtualized globals under VIMAGE_GLOBALS.
Bump __FreeBSD_version and update UPDATING.
Portions submitted by: bz
Reviewed by: bz, zec
Discussed with: gnn, jamie, jeff, jhb, julian, sam
Suggested by: peter
Approved by: re (kensmith)
2009-07-14 22:48:30 +00:00
|
|
|
|
|
|
|
VNET_DECLARE(struct in_ifaddrhashhead *, in_ifaddrhashtbl);
|
|
|
|
VNET_DECLARE(struct in_ifaddrhead, in_ifaddrhead);
|
|
|
|
VNET_DECLARE(u_long, in_ifaddrhmask); /* mask for hash table */
|
|
|
|
|
2009-07-16 21:13:04 +00:00
|
|
|
#define V_in_ifaddrhashtbl VNET(in_ifaddrhashtbl)
|
|
|
|
#define V_in_ifaddrhead VNET(in_ifaddrhead)
|
|
|
|
#define V_in_ifaddrhmask VNET(in_ifaddrhmask)
|
2001-09-29 04:34:11 +00:00
|
|
|
|
|
|
|
#define INADDR_NHASH_LOG2 9
|
|
|
|
#define INADDR_NHASH (1 << INADDR_NHASH_LOG2)
|
|
|
|
#define INADDR_HASHVAL(x) fnv_32_buf((&(x)), sizeof(x), FNV1_32_INIT)
|
|
|
|
#define INADDR_HASH(x) \
|
Commit step 1 of the vimage project, (network stack)
virtualization work done by Marko Zec (zec@).
This is the first in a series of commits over the course
of the next few weeks.
Mark all uses of global variables to be virtualized
with a V_ prefix.
Use macros to map them back to their global names for
now, so this is a NOP change only.
We hope to have caught at least 85-90% of what is needed
so we do not invalidate a lot of outstanding patches again.
Obtained from: //depot/projects/vimage-commit2/...
Reviewed by: brooks, des, ed, mav, julian,
jamie, kris, rwatson, zec, ...
(various people I forgot, different versions)
md5 (with a bit of help)
Sponsored by: NLnet Foundation, The FreeBSD Foundation
X-MFC after: never
V_Commit_Message_Reviewed_By: more people than the patch
2008-08-17 23:27:27 +00:00
|
|
|
(&V_in_ifaddrhashtbl[INADDR_HASHVAL(x) & V_in_ifaddrhmask])
|
2001-09-29 04:34:11 +00:00
|
|
|
|
2006-09-25 10:11:16 +00:00
|
|
|
/*
|
2006-09-25 11:48:07 +00:00
|
|
|
* Macro for finding the internet address structure (in_ifaddr)
|
2006-09-25 10:11:16 +00:00
|
|
|
* corresponding to one of our IP addresses (in_addr).
|
|
|
|
*/
|
|
|
|
#define INADDR_TO_IFADDR(addr, ia) \
|
|
|
|
/* struct in_addr addr; */ \
|
|
|
|
/* struct in_ifaddr *ia; */ \
|
2021-10-10 10:02:26 -07:00
|
|
|
do { \
|
|
|
|
NET_EPOCH_ASSERT(); \
|
|
|
|
CK_LIST_FOREACH(ia, INADDR_HASH((addr).s_addr), ia_hash) \
|
|
|
|
if (IA_SIN(ia)->sin_addr.s_addr == (addr).s_addr) \
|
|
|
|
break; \
|
2006-09-25 10:11:16 +00:00
|
|
|
} while (0)
|
2001-09-29 04:34:11 +00:00
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
/*
|
|
|
|
* Macro for finding the interface (ifnet structure) corresponding to one
|
|
|
|
* of our IP addresses.
|
|
|
|
*/
|
|
|
|
#define INADDR_TO_IFP(addr, ifp) \
|
|
|
|
/* struct in_addr addr; */ \
|
|
|
|
/* struct ifnet *ifp; */ \
|
|
|
|
{ \
|
2001-07-17 10:30:21 +00:00
|
|
|
struct in_ifaddr *ia; \
|
1994-05-24 10:09:53 +00:00
|
|
|
\
|
2006-09-25 10:11:16 +00:00
|
|
|
INADDR_TO_IFADDR(addr, ia); \
|
1994-05-24 10:09:53 +00:00
|
|
|
(ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Macro for finding the internet address structure (in_ifaddr) corresponding
|
|
|
|
* to a given interface (ifnet structure).
|
|
|
|
*/
|
2021-10-08 12:56:24 -07:00
|
|
|
#define IFP_TO_IA(ifp, ia) \
|
2009-06-23 20:19:09 +00:00
|
|
|
/* struct ifnet *ifp; */ \
|
|
|
|
/* struct in_ifaddr *ia; */ \
|
2012-07-18 08:41:00 +00:00
|
|
|
do { \
|
Widen NET_EPOCH coverage.
When epoch(9) was introduced to network stack, it was basically
dropped in place of existing locking, which was mutexes and
rwlocks. For the sake of performance mutex covered areas were
as small as possible, so became epoch covered areas.
However, epoch doesn't introduce any contention, it just delays
memory reclaim. So, there is no point to minimise epoch covered
areas in sense of performance. Meanwhile entering/exiting epoch
also has non-zero CPU usage, so doing this less often is a win.
Not the least is also code maintainability. In the new paradigm
we can assume that at any stage of processing a packet, we are
inside network epoch. This makes coding both input and output
path way easier.
On output path we already enter epoch quite early - in the
ip_output(), in the ip6_output().
This patch does the same for the input path. All ISR processing,
network related callouts, other ways of packet injection to the
network stack shall be performed in net_epoch. Any leaf function
that walks network configuration now asserts epoch.
Tricky part is configuration code paths - ioctls, sysctls. They
also call into leaf functions, so some need to be changed.
This patch would introduce more epoch recursions (see EPOCH_TRACE)
than we had before. They will be cleaned up separately, as several
of them aren't trivial. Note, that unlike a lock recursion the
epoch recursion is safe and just wastes a bit of resources.
Reviewed by: gallatin, hselasky, cy, adrian, kristof
Differential Revision: https://reviews.freebsd.org/D19111
2019-10-07 22:40:05 +00:00
|
|
|
NET_EPOCH_ASSERT(); \
|
2018-05-18 20:13:34 +00:00
|
|
|
for ((ia) = CK_STAILQ_FIRST(&V_in_ifaddrhead); \
|
2009-06-23 20:19:09 +00:00
|
|
|
(ia) != NULL && (ia)->ia_ifp != (ifp); \
|
2021-10-08 12:56:24 -07:00
|
|
|
(ia) = CK_STAILQ_NEXT((ia), ia_link)) \
|
2009-06-23 20:19:09 +00:00
|
|
|
continue; \
|
2012-07-18 08:41:00 +00:00
|
|
|
} while (0)
|
1994-05-24 10:09:53 +00:00
|
|
|
|
1994-09-06 22:42:31 +00:00
|
|
|
/*
|
2009-03-09 17:53:05 +00:00
|
|
|
* Legacy IPv4 IGMP per-link structure.
|
1994-09-06 22:42:31 +00:00
|
|
|
*/
|
|
|
|
struct router_info {
|
1996-03-14 16:59:20 +00:00
|
|
|
struct ifnet *rti_ifp;
|
|
|
|
int rti_type; /* type of router which is querier on this interface */
|
|
|
|
int rti_time; /* # of slow timeouts since last old query */
|
2003-08-20 17:09:01 +00:00
|
|
|
SLIST_ENTRY(router_info) rti_list;
|
1994-09-06 22:42:31 +00:00
|
|
|
};
|
|
|
|
|
2009-03-09 17:53:05 +00:00
|
|
|
/*
|
|
|
|
* IPv4 multicast IGMP-layer source entry.
|
|
|
|
*/
|
|
|
|
struct ip_msource {
|
|
|
|
RB_ENTRY(ip_msource) ims_link; /* RB tree links */
|
|
|
|
in_addr_t ims_haddr; /* host byte order */
|
|
|
|
struct ims_st {
|
|
|
|
uint16_t ex; /* # of exclusive members */
|
|
|
|
uint16_t in; /* # of inclusive members */
|
|
|
|
} ims_st[2]; /* state at t0, t1 */
|
|
|
|
uint8_t ims_stp; /* pending query */
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IPv4 multicast PCB-layer source entry.
|
|
|
|
*/
|
|
|
|
struct in_msource {
|
|
|
|
RB_ENTRY(ip_msource) ims_link; /* RB tree links */
|
|
|
|
in_addr_t ims_haddr; /* host byte order */
|
|
|
|
uint8_t imsl_st[2]; /* state before/at commit */
|
|
|
|
};
|
|
|
|
|
|
|
|
RB_HEAD(ip_msource_tree, ip_msource); /* define struct ip_msource_tree */
|
|
|
|
|
|
|
|
static __inline int
|
|
|
|
ip_msource_cmp(const struct ip_msource *a, const struct ip_msource *b)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (a->ims_haddr < b->ims_haddr)
|
|
|
|
return (-1);
|
|
|
|
if (a->ims_haddr == b->ims_haddr)
|
|
|
|
return (0);
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
RB_PROTOTYPE(ip_msource_tree, ip_msource, ims_link, ip_msource_cmp);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IPv4 multicast PCB-layer group filter descriptor.
|
|
|
|
*/
|
|
|
|
struct in_mfilter {
|
|
|
|
struct ip_msource_tree imf_sources; /* source list for (S,G) */
|
|
|
|
u_long imf_nsrc; /* # of source entries */
|
|
|
|
uint8_t imf_st[2]; /* state before/at commit */
|
2019-06-25 11:54:41 +00:00
|
|
|
struct in_multi *imf_inm; /* associated multicast address */
|
|
|
|
STAILQ_ENTRY(in_mfilter) imf_entry; /* list entry */
|
2009-03-09 17:53:05 +00:00
|
|
|
};
|
|
|
|
|
2019-06-25 11:54:41 +00:00
|
|
|
/*
|
|
|
|
* Helper types and functions for IPv4 multicast filters.
|
|
|
|
*/
|
|
|
|
STAILQ_HEAD(ip_mfilter_head, in_mfilter);
|
|
|
|
|
|
|
|
struct in_mfilter *ip_mfilter_alloc(int mflags, int st0, int st1);
|
|
|
|
void ip_mfilter_free(struct in_mfilter *);
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
ip_mfilter_init(struct ip_mfilter_head *head)
|
|
|
|
{
|
|
|
|
|
|
|
|
STAILQ_INIT(head);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline struct in_mfilter *
|
|
|
|
ip_mfilter_first(const struct ip_mfilter_head *head)
|
|
|
|
{
|
|
|
|
|
|
|
|
return (STAILQ_FIRST(head));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
ip_mfilter_insert(struct ip_mfilter_head *head, struct in_mfilter *imf)
|
|
|
|
{
|
|
|
|
|
|
|
|
STAILQ_INSERT_TAIL(head, imf, imf_entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
ip_mfilter_remove(struct ip_mfilter_head *head, struct in_mfilter *imf)
|
|
|
|
{
|
|
|
|
|
|
|
|
STAILQ_REMOVE(head, imf, in_mfilter, imf_entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define IP_MFILTER_FOREACH(imf, head) \
|
|
|
|
STAILQ_FOREACH(imf, head, imf_entry)
|
|
|
|
|
|
|
|
static inline size_t
|
|
|
|
ip_mfilter_count(struct ip_mfilter_head *head)
|
|
|
|
{
|
|
|
|
struct in_mfilter *imf;
|
|
|
|
size_t num = 0;
|
|
|
|
|
|
|
|
STAILQ_FOREACH(imf, head, imf_entry)
|
|
|
|
num++;
|
|
|
|
return (num);
|
|
|
|
}
|
|
|
|
|
2009-03-09 17:53:05 +00:00
|
|
|
/*
|
|
|
|
* IPv4 group descriptor.
|
|
|
|
*
|
|
|
|
* For every entry on an ifnet's if_multiaddrs list which represents
|
|
|
|
* an IP multicast group, there is one of these structures.
|
|
|
|
*
|
|
|
|
* If any source filters are present, then a node will exist in the RB-tree
|
|
|
|
* to permit fast lookup by source whenever an operation takes place.
|
|
|
|
* This permits pre-order traversal when we issue reports.
|
|
|
|
* Source filter trees are kept separately from the socket layer to
|
|
|
|
* greatly simplify locking.
|
|
|
|
*
|
|
|
|
* When IGMPv3 is active, inm_timer is the response to group query timer.
|
|
|
|
* The state-change timer inm_sctimer is separate; whenever state changes
|
|
|
|
* for the group the state change record is generated and transmitted,
|
|
|
|
* and kept if retransmissions are necessary.
|
|
|
|
*
|
|
|
|
* FUTURE: inm_link is now only used when groups are being purged
|
|
|
|
* on a detaching ifnet. It could be demoted to a SLIST_ENTRY, but
|
|
|
|
* because it is at the very start of the struct, we can't do this
|
|
|
|
* w/o breaking the ABI for ifmcstat.
|
1994-05-24 10:09:53 +00:00
|
|
|
*/
|
|
|
|
struct in_multi {
|
2009-03-09 17:53:05 +00:00
|
|
|
LIST_ENTRY(in_multi) inm_link; /* to-be-released by in_ifdetach */
|
1997-01-13 21:26:53 +00:00
|
|
|
struct in_addr inm_addr; /* IP multicast address, convenience */
|
1994-05-24 10:09:53 +00:00
|
|
|
struct ifnet *inm_ifp; /* back pointer to ifnet */
|
1997-01-13 21:26:53 +00:00
|
|
|
struct ifmultiaddr *inm_ifma; /* back pointer to ifmultiaddr */
|
2009-03-09 17:53:05 +00:00
|
|
|
u_int inm_timer; /* IGMPv1/v2 group / v3 query timer */
|
|
|
|
u_int inm_state; /* state of the membership */
|
|
|
|
void *inm_rti; /* unused, legacy field */
|
2007-03-20 00:36:10 +00:00
|
|
|
u_int inm_refcount; /* reference count */
|
2009-03-09 17:53:05 +00:00
|
|
|
|
|
|
|
/* New fields for IGMPv3 follow. */
|
2015-02-19 22:35:23 +00:00
|
|
|
struct igmp_ifsoftc *inm_igi; /* IGMP info */
|
2009-03-09 17:53:05 +00:00
|
|
|
SLIST_ENTRY(in_multi) inm_nrele; /* to-be-released by IGMP */
|
|
|
|
struct ip_msource_tree inm_srcs; /* tree of sources */
|
|
|
|
u_long inm_nsrc; /* # of tree entries */
|
|
|
|
|
2015-02-19 01:21:02 +00:00
|
|
|
struct mbufq inm_scq; /* queue of pending
|
2009-03-09 17:53:05 +00:00
|
|
|
* state-change packets */
|
|
|
|
struct timeval inm_lastgsrtv; /* Time of last G-S-R query */
|
|
|
|
uint16_t inm_sctimer; /* state-change timer */
|
|
|
|
uint16_t inm_scrv; /* state-change rexmit count */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SSM state counters which track state at T0 (the time the last
|
|
|
|
* state-change report's RV timer went to zero) and T1
|
|
|
|
* (time of pending report, i.e. now).
|
|
|
|
* Used for computing IGMPv3 state-change reports. Several refcounts
|
|
|
|
* are maintained here to optimize for common use-cases.
|
|
|
|
*/
|
|
|
|
struct inm_st {
|
|
|
|
uint16_t iss_fmode; /* IGMP filter mode */
|
|
|
|
uint16_t iss_asm; /* # of ASM listeners */
|
|
|
|
uint16_t iss_ex; /* # of exclusive members */
|
|
|
|
uint16_t iss_in; /* # of inclusive members */
|
|
|
|
uint16_t iss_rec; /* # of recorded sources */
|
|
|
|
} inm_st[2]; /* state at t0, t1 */
|
Import rewrite of IPv4 socket multicast layer to support source-specific
and protocol-independent host mode multicast. The code is written to
accomodate IPv6, IGMPv3 and MLDv2 with only a little additional work.
This change only pertains to FreeBSD's use as a multicast end-station and
does not concern multicast routing; for an IGMPv3/MLDv2 router
implementation, consider the XORP project.
The work is based on Wilbert de Graaf's IGMPv3 code drop for FreeBSD 4.6,
which is available at: http://www.kloosterhof.com/wilbert/igmpv3.html
Summary
* IPv4 multicast socket processing is now moved out of ip_output.c
into a new module, in_mcast.c.
* The in_mcast.c module implements the IPv4 legacy any-source API in
terms of the protocol-independent source-specific API.
* Source filters are lazy allocated as the common case does not use them.
They are part of per inpcb state and are covered by the inpcb lock.
* struct ip_mreqn is now supported to allow applications to specify
multicast joins by interface index in the legacy IPv4 any-source API.
* In UDP, an incoming multicast datagram only requires that the source
port matches the 4-tuple if the socket was already bound by source port.
An unbound socket SHOULD be able to receive multicasts sent from an
ephemeral source port.
* The UDP socket multicast filter mode defaults to exclusive, that is,
sources present in the per-socket list will be blocked from delivery.
* The RFC 3678 userland functions have been added to libc: setsourcefilter,
getsourcefilter, setipv4sourcefilter, getipv4sourcefilter.
* Definitions for IGMPv3 are merged but not yet used.
* struct sockaddr_storage is now referenced from <netinet/in.h>. It
is therefore defined there if not already declared in the same way
as for the C99 types.
* The RFC 1724 hack (specify 0.0.0.0/8 addresses to IP_MULTICAST_IF
which are then interpreted as interface indexes) is now deprecated.
* A patch for the Rhyolite.com routed in the FreeBSD base system
is available in the -net archives. This only affects individuals
running RIPv1 or RIPv2 via point-to-point and/or unnumbered interfaces.
* Make IPv6 detach path similar to IPv4's in code flow; functionally same.
* Bump __FreeBSD_version to 700048; see UPDATING.
This work was financially supported by another FreeBSD committer.
Obtained from: p4://bms_netdev
Submitted by: Wilbert de Graaf (original work)
Reviewed by: rwatson (locking), silence from fenner,
net@ (but with encouragement)
2007-06-12 16:24:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
2009-03-09 17:53:05 +00:00
|
|
|
* Helper function to derive the filter mode on a source entry
|
|
|
|
* from its internal counters. Predicates are:
|
|
|
|
* A source is only excluded if all listeners exclude it.
|
|
|
|
* A source is only included if no listeners exclude it,
|
|
|
|
* and at least one listener includes it.
|
|
|
|
* May be used by ifmcstat(8).
|
Import rewrite of IPv4 socket multicast layer to support source-specific
and protocol-independent host mode multicast. The code is written to
accomodate IPv6, IGMPv3 and MLDv2 with only a little additional work.
This change only pertains to FreeBSD's use as a multicast end-station and
does not concern multicast routing; for an IGMPv3/MLDv2 router
implementation, consider the XORP project.
The work is based on Wilbert de Graaf's IGMPv3 code drop for FreeBSD 4.6,
which is available at: http://www.kloosterhof.com/wilbert/igmpv3.html
Summary
* IPv4 multicast socket processing is now moved out of ip_output.c
into a new module, in_mcast.c.
* The in_mcast.c module implements the IPv4 legacy any-source API in
terms of the protocol-independent source-specific API.
* Source filters are lazy allocated as the common case does not use them.
They are part of per inpcb state and are covered by the inpcb lock.
* struct ip_mreqn is now supported to allow applications to specify
multicast joins by interface index in the legacy IPv4 any-source API.
* In UDP, an incoming multicast datagram only requires that the source
port matches the 4-tuple if the socket was already bound by source port.
An unbound socket SHOULD be able to receive multicasts sent from an
ephemeral source port.
* The UDP socket multicast filter mode defaults to exclusive, that is,
sources present in the per-socket list will be blocked from delivery.
* The RFC 3678 userland functions have been added to libc: setsourcefilter,
getsourcefilter, setipv4sourcefilter, getipv4sourcefilter.
* Definitions for IGMPv3 are merged but not yet used.
* struct sockaddr_storage is now referenced from <netinet/in.h>. It
is therefore defined there if not already declared in the same way
as for the C99 types.
* The RFC 1724 hack (specify 0.0.0.0/8 addresses to IP_MULTICAST_IF
which are then interpreted as interface indexes) is now deprecated.
* A patch for the Rhyolite.com routed in the FreeBSD base system
is available in the -net archives. This only affects individuals
running RIPv1 or RIPv2 via point-to-point and/or unnumbered interfaces.
* Make IPv6 detach path similar to IPv4's in code flow; functionally same.
* Bump __FreeBSD_version to 700048; see UPDATING.
This work was financially supported by another FreeBSD committer.
Obtained from: p4://bms_netdev
Submitted by: Wilbert de Graaf (original work)
Reviewed by: rwatson (locking), silence from fenner,
net@ (but with encouragement)
2007-06-12 16:24:56 +00:00
|
|
|
*/
|
2009-03-09 17:53:05 +00:00
|
|
|
static __inline uint8_t
|
|
|
|
ims_get_mode(const struct in_multi *inm, const struct ip_msource *ims,
|
|
|
|
uint8_t t)
|
|
|
|
{
|
|
|
|
|
|
|
|
t = !!t;
|
|
|
|
if (inm->inm_st[t].iss_ex > 0 &&
|
|
|
|
inm->inm_st[t].iss_ex == ims->ims_st[t].ex)
|
|
|
|
return (MCAST_EXCLUDE);
|
|
|
|
else if (ims->ims_st[t].in > 0 && ims->ims_st[t].ex == 0)
|
|
|
|
return (MCAST_INCLUDE);
|
|
|
|
return (MCAST_UNDEFINED);
|
|
|
|
}
|
1994-05-24 10:09:53 +00:00
|
|
|
|
1999-02-16 10:49:55 +00:00
|
|
|
#ifdef SYSCTL_DECL
|
2004-10-19 21:06:14 +00:00
|
|
|
SYSCTL_DECL(_net_inet);
|
1999-02-16 10:49:55 +00:00
|
|
|
SYSCTL_DECL(_net_inet_ip);
|
|
|
|
SYSCTL_DECL(_net_inet_raw);
|
|
|
|
#endif
|
|
|
|
|
Introduce in_multi_mtx, which will protect IPv4-layer multicast address
lists, as well as accessor macros. For now, this is a recursive mutex
due code sequences where IPv4 multicast calls into IGMP calls into
ip_output(), which then tests for a multicast forwarding case.
For support macros in in_var.h to check multicast address lists, assert
that in_multi_mtx is held.
Acquire in_multi_mtx around iteration over the IPv4 multicast address
lists, such as in ip_input() and ip_output().
Acquire in_multi_mtx when manipulating the IPv4 layer multicast addresses,
as well as over the manipulation of ifnet multicast address lists in order
to keep the two layers in sync.
Lock down accesses to IPv4 multicast addresses in IGMP, or assert the
lock when performing IGMP join/leave events.
Eliminate spl's associated with IPv4 multicast addresses, portions of
IGMP that weren't previously expunged by IGMP locking.
Add in_multi_mtx, igmp_mtx, and if_addr_mtx lock order to hard-coded
lock order in WITNESS, in that order.
Problem reported by: Ed Maste <emaste at phaedrus dot sandvine dot ca>
MFC after: 10 days
2005-08-03 19:29:47 +00:00
|
|
|
/*
|
|
|
|
* Lock macros for IPv4 layer multicast address lists. IPv4 lock goes
|
|
|
|
* before link layer multicast locks in the lock order. In most cases,
|
|
|
|
* consumers of IN_*_MULTI() macros should acquire the locks before
|
|
|
|
* calling them; users of the in_{add,del}multi() functions should not.
|
|
|
|
*/
|
2018-05-02 19:36:29 +00:00
|
|
|
extern struct mtx in_multi_list_mtx;
|
|
|
|
extern struct sx in_multi_sx;
|
|
|
|
|
|
|
|
#define IN_MULTI_LIST_LOCK() mtx_lock(&in_multi_list_mtx)
|
|
|
|
#define IN_MULTI_LIST_UNLOCK() mtx_unlock(&in_multi_list_mtx)
|
|
|
|
#define IN_MULTI_LIST_LOCK_ASSERT() mtx_assert(&in_multi_list_mtx, MA_OWNED)
|
|
|
|
#define IN_MULTI_LIST_UNLOCK_ASSERT() mtx_assert(&in_multi_list_mtx, MA_NOTOWNED)
|
|
|
|
|
|
|
|
#define IN_MULTI_LOCK() sx_xlock(&in_multi_sx)
|
|
|
|
#define IN_MULTI_UNLOCK() sx_xunlock(&in_multi_sx)
|
|
|
|
#define IN_MULTI_LOCK_ASSERT() sx_assert(&in_multi_sx, SA_XLOCKED)
|
|
|
|
#define IN_MULTI_UNLOCK_ASSERT() sx_assert(&in_multi_sx, SA_XUNLOCKED)
|
Introduce in_multi_mtx, which will protect IPv4-layer multicast address
lists, as well as accessor macros. For now, this is a recursive mutex
due code sequences where IPv4 multicast calls into IGMP calls into
ip_output(), which then tests for a multicast forwarding case.
For support macros in in_var.h to check multicast address lists, assert
that in_multi_mtx is held.
Acquire in_multi_mtx around iteration over the IPv4 multicast address
lists, such as in ip_input() and ip_output().
Acquire in_multi_mtx when manipulating the IPv4 layer multicast addresses,
as well as over the manipulation of ifnet multicast address lists in order
to keep the two layers in sync.
Lock down accesses to IPv4 multicast addresses in IGMP, or assert the
lock when performing IGMP join/leave events.
Eliminate spl's associated with IPv4 multicast addresses, portions of
IGMP that weren't previously expunged by IGMP locking.
Add in_multi_mtx, igmp_mtx, and if_addr_mtx lock order to hard-coded
lock order in WITNESS, in that order.
Problem reported by: Ed Maste <emaste at phaedrus dot sandvine dot ca>
MFC after: 10 days
2005-08-03 19:29:47 +00:00
|
|
|
|
2018-05-06 20:34:13 +00:00
|
|
|
void inm_disconnect(struct in_multi *inm);
|
|
|
|
extern int ifma_restart;
|
|
|
|
|
2009-03-09 17:53:05 +00:00
|
|
|
/* Acquire an in_multi record. */
|
|
|
|
static __inline void
|
|
|
|
inm_acquire_locked(struct in_multi *inm)
|
|
|
|
{
|
|
|
|
|
2018-05-02 19:36:29 +00:00
|
|
|
IN_MULTI_LIST_LOCK_ASSERT();
|
2009-03-09 17:53:05 +00:00
|
|
|
++inm->inm_refcount;
|
|
|
|
}
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2018-05-02 19:36:29 +00:00
|
|
|
static __inline void
|
|
|
|
inm_acquire(struct in_multi *inm)
|
|
|
|
{
|
|
|
|
IN_MULTI_LIST_LOCK();
|
|
|
|
inm_acquire_locked(inm);
|
|
|
|
IN_MULTI_LIST_UNLOCK();
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
inm_rele_locked(struct in_multi_head *inmh, struct in_multi *inm)
|
|
|
|
{
|
|
|
|
MPASS(inm->inm_refcount > 0);
|
|
|
|
IN_MULTI_LIST_LOCK_ASSERT();
|
|
|
|
|
|
|
|
if (--inm->inm_refcount == 0) {
|
|
|
|
MPASS(inmh != NULL);
|
2018-05-06 20:34:13 +00:00
|
|
|
inm_disconnect(inm);
|
2018-05-02 19:36:29 +00:00
|
|
|
inm->inm_ifma->ifma_protospec = NULL;
|
|
|
|
SLIST_INSERT_HEAD(inmh, inm, inm_nrele);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1994-05-24 10:09:53 +00:00
|
|
|
/*
|
2009-03-09 17:53:05 +00:00
|
|
|
* Return values for imo_multi_filter().
|
1994-05-24 10:09:53 +00:00
|
|
|
*/
|
2009-03-09 17:53:05 +00:00
|
|
|
#define MCAST_PASS 0 /* Pass */
|
|
|
|
#define MCAST_NOTGMEMBER 1 /* This host not a member of group */
|
|
|
|
#define MCAST_NOTSMEMBER 2 /* This host excluded source */
|
|
|
|
#define MCAST_MUTED 3 /* [deprecated] */
|
1994-05-24 10:09:53 +00:00
|
|
|
|
2020-08-14 21:29:56 +00:00
|
|
|
struct rib_head;
|
Import rewrite of IPv4 socket multicast layer to support source-specific
and protocol-independent host mode multicast. The code is written to
accomodate IPv6, IGMPv3 and MLDv2 with only a little additional work.
This change only pertains to FreeBSD's use as a multicast end-station and
does not concern multicast routing; for an IGMPv3/MLDv2 router
implementation, consider the XORP project.
The work is based on Wilbert de Graaf's IGMPv3 code drop for FreeBSD 4.6,
which is available at: http://www.kloosterhof.com/wilbert/igmpv3.html
Summary
* IPv4 multicast socket processing is now moved out of ip_output.c
into a new module, in_mcast.c.
* The in_mcast.c module implements the IPv4 legacy any-source API in
terms of the protocol-independent source-specific API.
* Source filters are lazy allocated as the common case does not use them.
They are part of per inpcb state and are covered by the inpcb lock.
* struct ip_mreqn is now supported to allow applications to specify
multicast joins by interface index in the legacy IPv4 any-source API.
* In UDP, an incoming multicast datagram only requires that the source
port matches the 4-tuple if the socket was already bound by source port.
An unbound socket SHOULD be able to receive multicasts sent from an
ephemeral source port.
* The UDP socket multicast filter mode defaults to exclusive, that is,
sources present in the per-socket list will be blocked from delivery.
* The RFC 3678 userland functions have been added to libc: setsourcefilter,
getsourcefilter, setipv4sourcefilter, getipv4sourcefilter.
* Definitions for IGMPv3 are merged but not yet used.
* struct sockaddr_storage is now referenced from <netinet/in.h>. It
is therefore defined there if not already declared in the same way
as for the C99 types.
* The RFC 1724 hack (specify 0.0.0.0/8 addresses to IP_MULTICAST_IF
which are then interpreted as interface indexes) is now deprecated.
* A patch for the Rhyolite.com routed in the FreeBSD base system
is available in the -net archives. This only affects individuals
running RIPv1 or RIPv2 via point-to-point and/or unnumbered interfaces.
* Make IPv6 detach path similar to IPv4's in code flow; functionally same.
* Bump __FreeBSD_version to 700048; see UPDATING.
This work was financially supported by another FreeBSD committer.
Obtained from: p4://bms_netdev
Submitted by: Wilbert de Graaf (original work)
Reviewed by: rwatson (locking), silence from fenner,
net@ (but with encouragement)
2007-06-12 16:24:56 +00:00
|
|
|
struct ip_moptions;
|
|
|
|
|
2013-10-29 11:21:31 +00:00
|
|
|
struct in_multi *inm_lookup_locked(struct ifnet *, const struct in_addr);
|
|
|
|
struct in_multi *inm_lookup(struct ifnet *, const struct in_addr);
|
2009-03-09 17:53:05 +00:00
|
|
|
int imo_multi_filter(const struct ip_moptions *, const struct ifnet *,
|
|
|
|
const struct sockaddr *, const struct sockaddr *);
|
|
|
|
void inm_commit(struct in_multi *);
|
|
|
|
void inm_clear_recorded(struct in_multi *);
|
|
|
|
void inm_print(const struct in_multi *);
|
|
|
|
int inm_record_source(struct in_multi *inm, const in_addr_t);
|
2018-05-02 19:36:29 +00:00
|
|
|
void inm_release_deferred(struct in_multi *);
|
|
|
|
void inm_release_list_deferred(struct in_multi_head *);
|
2020-08-10 10:46:08 +00:00
|
|
|
void inm_release_wait(void *);
|
2009-03-09 17:53:05 +00:00
|
|
|
int in_joingroup(struct ifnet *, const struct in_addr *,
|
|
|
|
/*const*/ struct in_mfilter *, struct in_multi **);
|
|
|
|
int in_joingroup_locked(struct ifnet *, const struct in_addr *,
|
|
|
|
/*const*/ struct in_mfilter *, struct in_multi **);
|
|
|
|
int in_leavegroup(struct in_multi *, /*const*/ struct in_mfilter *);
|
|
|
|
int in_leavegroup_locked(struct in_multi *,
|
|
|
|
/*const*/ struct in_mfilter *);
|
2002-03-19 21:25:46 +00:00
|
|
|
int in_control(struct socket *, u_long, caddr_t, struct ifnet *,
|
2002-03-24 10:19:10 +00:00
|
|
|
struct thread *);
|
2021-01-19 23:50:34 +00:00
|
|
|
int in_addprefix(struct in_ifaddr *);
|
A major overhaul of the CARP implementation. The ip_carp.c was started
from scratch, copying needed functionality from the old implemenation
on demand, with a thorough review of all code. The main change is that
interface layer has been removed from the CARP. Now redundant addresses
are configured exactly on the interfaces, they run on.
The CARP configuration itself is, as before, configured and read via
SIOCSVH/SIOCGVH ioctls. A new prefix created with SIOCAIFADDR or
SIOCAIFADDR_IN6 may now be configured to a particular virtual host id,
which makes the prefix redundant.
ifconfig(8) semantics has been changed too: now one doesn't need
to clone carpXX interface, he/she should directly configure a vhid
on a Ethernet interface.
To supply vhid data from the kernel to an application the getifaddrs(8)
function had been changed to pass ifam_data with each address. [1]
The new implementation definitely closes all PRs related to carp(4)
being an interface, and may close several others. It also allows
to run a single redundant IP per interface.
Big thanks to Bjoern Zeeb for his help with inet6 part of patch, for
idea on using ifam_data and for several rounds of reviewing!
PR: kern/117000, kern/126945, kern/126714, kern/120130, kern/117448
Reviewed by: bz
Submitted by: bz [1]
2011-12-16 12:16:56 +00:00
|
|
|
int in_scrubprefix(struct in_ifaddr *, u_int);
|
Get closer to a VIMAGE network stack teardown from top to bottom rather
than removing the network interfaces first. This change is rather larger
and convoluted as the ordering requirements cannot be separated.
Move the pfil(9) framework to SI_SUB_PROTO_PFIL, move Firewalls and
related modules to their own SI_SUB_PROTO_FIREWALL.
Move initialization of "physical" interfaces to SI_SUB_DRIVERS,
move virtual (cloned) interfaces to SI_SUB_PSEUDO.
Move Multicast to SI_SUB_PROTO_MC.
Re-work parts of multicast initialisation and teardown, not taking the
huge amount of memory into account if used as a module yet.
For interface teardown we try to do as many of them as we can on
SI_SUB_INIT_IF, but for some this makes no sense, e.g., when tunnelling
over a higher layer protocol such as IP. In that case the interface
has to go along (or before) the higher layer protocol is shutdown.
Kernel hhooks need to go last on teardown as they may be used at various
higher layers and we cannot remove them before we cleaned up the higher
layers.
For interface teardown there are multiple paths:
(a) a cloned interface is destroyed (inside a VIMAGE or in the base system),
(b) any interface is moved from a virtual network stack to a different
network stack ("vmove"), or (c) a virtual network stack is being shut down.
All code paths go through if_detach_internal() where we, depending on the
vmove flag or the vnet state, make a decision on how much to shut down;
in case we are destroying a VNET the individual protocol layers will
cleanup their own parts thus we cannot do so again for each interface as
we end up with, e.g., double-frees, destroying locks twice or acquiring
already destroyed locks.
When calling into protocol cleanups we equally have to tell them
whether they need to detach upper layer protocols ("ulp") or not
(e.g., in6_ifdetach()).
Provide or enahnce helper functions to do proper cleanup at a protocol
rather than at an interface level.
Approved by: re (hrs)
Obtained from: projects/vnet
Reviewed by: gnn, jhb
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D6747
2016-06-21 13:48:49 +00:00
|
|
|
void in_ifscrub_all(void);
|
Split rtinit() into multiple functions.
rtinit[1]() is a function used to add or remove interface address prefix routes,
similar to ifa_maintain_loopback_route().
It was intended to be family-agnostic. There is a problem with this approach
in reality.
1) IPv6 code does not use it for the ifa routes. There is a separate layer,
nd6_prelist_(), providing interface for maintaining interface routes. Its part,
responsible for the actual route table interaction, mimics rtenty() code.
2) rtinit tries to combine multiple actions in the same function: constructing
proper route attributes and handling iterations over multiple fibs, for the
non-zero net.add_addr_allfibs use case. It notably increases the code complexity.
3) dstaddr handling. flags parameter re-uses RTF_ flags. As there is no special flag
for p2p connections, host routes and p2p routes are handled in the same way.
Additionally, mapping IFA flags to RTF flags makes the interface pretty messy.
It make rtinit() to clash with ifa_mainain_loopback_route() for IPV4 interface
aliases.
4) rtinit() is the last customer passing non-masked prefixes to rib_action(),
complicating rib_action() implementation.
5) rtinit() coupled ifa announce/withdrawal notifications, producing "false positive"
ifa messages in certain corner cases.
To address all these points, the following has been done:
* rtinit() has been split into multiple functions:
- Route attribute construction were moved to the per-address-family functions,
dealing with (2), (3) and (4).
- funnction providing net.add_addr_allfibs handling and route rtsock notificaions
is the new routing table inteface.
- rtsock ifa notificaion has been moved out as well. resulting set of funcion are only
responsible for the actual route notifications.
Side effects:
* /32 alias does not result in interface routes (/32 route and "host" route)
* RTF_PINNED is now set for IPv6 prefixes corresponding to the interface addresses
Differential revision: https://reviews.freebsd.org/D28186
2021-01-09 00:19:25 +00:00
|
|
|
int in_handle_ifaddr_route(int, struct in_ifaddr *);
|
2002-03-19 21:25:46 +00:00
|
|
|
void ip_input(struct mbuf *);
|
2014-09-09 04:18:20 +00:00
|
|
|
void ip_direct_input(struct mbuf *);
|
2013-11-01 10:29:10 +00:00
|
|
|
void in_ifadown(struct ifaddr *ifa, int);
|
2015-11-05 07:26:32 +00:00
|
|
|
struct mbuf *ip_tryforward(struct mbuf *);
|
This main goals of this project are:
1. separating L2 tables (ARP, NDP) from the L3 routing tables
2. removing as much locking dependencies among these layers as
possible to allow for some parallelism in the search operations
3. simplify the logic in the routing code,
The most notable end result is the obsolescent of the route
cloning (RTF_CLONING) concept, which translated into code reduction
in both IPv4 ARP and IPv6 NDP related modules, and size reduction in
struct rtentry{}. The change in design obsoletes the semantics of
RTF_CLONING, RTF_WASCLONE and RTF_LLINFO routing flags. The userland
applications such as "arp" and "ndp" have been modified to reflect
those changes. The output from "netstat -r" shows only the routing
entries.
Quite a few developers have contributed to this project in the
past: Glebius Smirnoff, Luigi Rizzo, Alessandro Cerri, and
Andre Oppermann. And most recently:
- Kip Macy revised the locking code completely, thus completing
the last piece of the puzzle, Kip has also been conducting
active functional testing
- Sam Leffler has helped me improving/refactoring the code, and
provided valuable reviews
- Julian Elischer setup the perforce tree for me and has helped
me maintaining that branch before the svn conversion
2008-12-15 06:10:57 +00:00
|
|
|
void *in_domifattach(struct ifnet *);
|
|
|
|
void in_domifdetach(struct ifnet *, void *);
|
2020-08-14 21:29:56 +00:00
|
|
|
struct rib_head *in_inithead(uint32_t fibnum);
|
|
|
|
#ifdef VIMAGE
|
|
|
|
void in_detachhead(struct rib_head *rh);
|
|
|
|
#endif
|
This main goals of this project are:
1. separating L2 tables (ARP, NDP) from the L3 routing tables
2. removing as much locking dependencies among these layers as
possible to allow for some parallelism in the search operations
3. simplify the logic in the routing code,
The most notable end result is the obsolescent of the route
cloning (RTF_CLONING) concept, which translated into code reduction
in both IPv4 ARP and IPv6 NDP related modules, and size reduction in
struct rtentry{}. The change in design obsoletes the semantics of
RTF_CLONING, RTF_WASCLONE and RTF_LLINFO routing flags. The userland
applications such as "arp" and "ndp" have been modified to reflect
those changes. The output from "netstat -r" shows only the routing
entries.
Quite a few developers have contributed to this project in the
past: Glebius Smirnoff, Luigi Rizzo, Alessandro Cerri, and
Andre Oppermann. And most recently:
- Kip Macy revised the locking code completely, thus completing
the last piece of the puzzle, Kip has also been conducting
active functional testing
- Sam Leffler has helped me improving/refactoring the code, and
provided valuable reviews
- Julian Elischer setup the perforce tree for me and has helped
me maintaining that branch before the svn conversion
2008-12-15 06:10:57 +00:00
|
|
|
|
1999-12-29 04:46:21 +00:00
|
|
|
#endif /* _KERNEL */
|
1995-09-21 17:50:45 +00:00
|
|
|
|
1999-11-05 14:41:39 +00:00
|
|
|
/* INET6 stuff */
|
|
|
|
#include <netinet6/in6_var.h>
|
|
|
|
|
1995-09-21 17:50:45 +00:00
|
|
|
#endif /* _NETINET_IN_VAR_H_ */
|