summaryrefslogtreecommitdiffstats
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2014-01-09 18:13:25 +0000
committermelifaro <melifaro@FreeBSD.org>2014-01-09 18:13:25 +0000
commitdfba7fd9efde812714b9c0170866c37a2309a17d (patch)
tree2991c09c03373266c319af320eea1ef1d87cc955 /sys/net/rtsock.c
parentc6e000e23a3fb4c828bb1d110c6718a8d6ed1738 (diff)
downloadFreeBSD-src-dfba7fd9efde812714b9c0170866c37a2309a17d.zip
FreeBSD-src-dfba7fd9efde812714b9c0170866c37a2309a17d.tar.gz
Split rt_newaddrmsg_fib() into two different functions.
Adding/deleting interface addresses involves access to 3 different subsystems, int different parts of code. Each call can fail, so reporting successful operation by rtsock in the middle of the process error-prone. Further split routing notification API and actual rtsock calls via creating public-available rt_addrmsg() / rt_routemsg() functions with "private" rtsock_* backend. MFC after: 2 weeks
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c153
1 files changed, 75 insertions, 78 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 98cccb3..2e7f6f4 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -30,7 +30,6 @@
* $FreeBSD$
*/
#include "opt_compat.h"
-#include "opt_sctp.h"
#include "opt_mpath.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -70,12 +69,6 @@
#include <netinet6/scope6_var.h>
#endif
-#if defined(INET) || defined(INET6)
-#ifdef SCTP
-extern void sctp_addr_change(struct ifaddr *ifa, int cmd);
-#endif /* SCTP */
-#endif
-
#ifdef COMPAT_FREEBSD32
#include <sys/mount.h>
#include <compat/freebsd32/freebsd32.h>
@@ -1334,91 +1327,95 @@ rt_ifmsg(struct ifnet *ifp)
}
/*
- * This is called to generate messages from the routing socket
- * indicating a network interface has had addresses associated with it.
- * if we ever reverse the logic and replace messages TO the routing
- * socket indicate a request to configure interfaces, then it will
- * be unnecessary as the routing socket will automatically generate
- * copies of it.
+ * Announce interface address arrival/withdraw.
+ * Please do not call directly, use rt_addrmsg().
+ * Assume input data to be valid.
+ * Returns 0 on success.
*/
-void
-rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt,
- int fibnum)
+int
+rtsock_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
{
struct rt_addrinfo info;
- struct sockaddr *sa = NULL;
- int pass;
- struct mbuf *m = NULL;
+ struct sockaddr *sa;
+ int ncmd;
+ struct mbuf *m;
+ struct ifa_msghdr *ifam;
struct ifnet *ifp = ifa->ifa_ifp;
- KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
- ("unexpected cmd %u", cmd));
-#if defined(INET) || defined(INET6)
-#ifdef SCTP
- /*
- * notify the SCTP stack
- * this will only get called when an address is added/deleted
- * XXX pass the ifaddr struct instead if ifa->ifa_addr...
- */
- sctp_addr_change(ifa, cmd);
-#endif /* SCTP */
-#endif
if (route_cb.any_count == 0)
- return;
- for (pass = 1; pass < 3; pass++) {
- bzero((caddr_t)&info, sizeof(info));
- if ((cmd == RTM_ADD && pass == 1) ||
- (cmd == RTM_DELETE && pass == 2)) {
- struct ifa_msghdr *ifam;
- int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;
-
- info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
- info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr;
- info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
- info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
- if ((m = rt_msg1(ncmd, &info)) == NULL)
- continue;
- ifam = mtod(m, struct ifa_msghdr *);
- ifam->ifam_index = ifp->if_index;
- ifam->ifam_metric = ifa->ifa_metric;
- ifam->ifam_flags = ifa->ifa_flags;
- ifam->ifam_addrs = info.rti_addrs;
- }
- if ((cmd == RTM_ADD && pass == 2) ||
- (cmd == RTM_DELETE && pass == 1)) {
- struct rt_msghdr *rtm;
+ return (0);
- if (rt == NULL)
- continue;
- info.rti_info[RTAX_NETMASK] = rt_mask(rt);
- info.rti_info[RTAX_DST] = sa = rt_key(rt);
- info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
- if ((m = rt_msg1(cmd, &info)) == NULL)
- continue;
- rtm = mtod(m, struct rt_msghdr *);
- rtm->rtm_index = ifp->if_index;
- rtm->rtm_flags |= rt->rt_flags;
- rtm->rtm_errno = error;
- rtm->rtm_addrs = info.rti_addrs;
- }
- if (fibnum != RT_ALL_FIBS) {
- KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: "
- "fibnum out of range 0 <= %d < %d", __func__,
- fibnum, rt_numfibs));
- M_SETFIB(m, fibnum);
- m->m_flags |= RTS_FILTER_FIB;
- }
- rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC);
+ ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;
+
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
+ info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr;
+ info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
+ info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
+ if ((m = rt_msg1(ncmd, &info)) == NULL)
+ return (ENOBUFS);
+ ifam = mtod(m, struct ifa_msghdr *);
+ ifam->ifam_index = ifp->if_index;
+ ifam->ifam_metric = ifa->ifa_metric;
+ ifam->ifam_flags = ifa->ifa_flags;
+ ifam->ifam_addrs = info.rti_addrs;
+
+ if (fibnum != RT_ALL_FIBS) {
+ M_SETFIB(m, fibnum);
+ m->m_flags |= RTS_FILTER_FIB;
}
+
+ rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC);
+
+ return (0);
}
-void
-rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
+/*
+ * Announce route addition/removal.
+ * Please do not call directly, use rt_routemsg().
+ * Note that @rt data MAY be inconsistent/invalid:
+ * if some userland app sends us "invalid" route message (invalid mask,
+ * no dst, wrong address families, etc...) we need to pass it back
+ * to app (and any other rtsock consumers) with rtm_errno field set to
+ * non-zero value.
+ *
+ * Returns 0 on success.
+ */
+int
+rtsock_routemsg(int cmd, struct ifnet *ifp, int error, struct rtentry *rt,
+ int fibnum)
{
+ struct rt_addrinfo info;
+ struct sockaddr *sa;
+ struct mbuf *m;
+ struct rt_msghdr *rtm;
+
+ if (route_cb.any_count == 0)
+ return (0);
- rt_newaddrmsg_fib(cmd, ifa, error, rt, RT_ALL_FIBS);
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+ info.rti_info[RTAX_DST] = sa = rt_key(rt);
+ info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+ if ((m = rt_msg1(cmd, &info)) == NULL)
+ return (ENOBUFS);
+ rtm = mtod(m, struct rt_msghdr *);
+ rtm->rtm_index = ifp->if_index;
+ rtm->rtm_flags |= rt->rt_flags;
+ rtm->rtm_errno = error;
+ rtm->rtm_addrs = info.rti_addrs;
+
+ if (fibnum != RT_ALL_FIBS) {
+ M_SETFIB(m, fibnum);
+ m->m_flags |= RTS_FILTER_FIB;
+ }
+
+ rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC);
+
+ return (0);
}
+
/*
* This is the analogue to the rt_newaddrmsg which performs the same
* function but for multicast group memberhips. This is easier since
OpenPOWER on IntegriCloud