Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160402759
D55804.id173538.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D55804.id173538.diff
View Options
diff --git a/sys/net/if.c b/sys/net/if.c
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -248,7 +248,6 @@
int (*carp_forus_p)(struct ifnet *ifp, u_char *dhost);
int (*carp_output_p)(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *sa);
-int (*carp_ioctl_p)(struct ifreq *, u_long, struct thread *);
int (*carp_attach_p)(struct ifaddr *, int);
void (*carp_detach_p)(struct ifaddr *, bool);
#endif
@@ -2923,15 +2922,6 @@
error = if_getgroupmembers(req);
goto out_noref;
}
-#if defined(INET) || defined(INET6)
- case SIOCSVH:
- case SIOCGVH:
- if (carp_ioctl_p == NULL)
- error = EPROTONOSUPPORT;
- else
- error = (*carp_ioctl_p)(ifr, cmd, td);
- goto out_noref;
-#endif
}
ifp = ifunit_ref(ifr->ifr_name);
diff --git a/sys/netinet/ip_carp.h b/sys/netinet/ip_carp.h
--- a/sys/netinet/ip_carp.h
+++ b/sys/netinet/ip_carp.h
@@ -160,23 +160,10 @@
uint64_t carps_preempt; /* if enabled, preemptions */
};
-/*
- * Configuration structure for SIOCSVH SIOCGVH
- */
-struct carpreq {
- int carpr_count;
- int carpr_vhid;
#define CARP_MAXVHID 255
- int carpr_state;
#define CARP_STATES "INIT", "BACKUP", "MASTER"
#define CARP_MAXSTATE 2
- int carpr_advskew;
#define CARP_MAXSKEW 240
- int carpr_advbase;
- unsigned char carpr_key[CARP_KEY_LEN];
-};
-#define SIOCSVH _IOWR('i', 245, struct ifreq)
-#define SIOCGVH _IOWR('i', 246, struct ifreq)
typedef enum carp_version {
CARP_VERSION_CARP = 2,
@@ -198,7 +185,6 @@
/* These are external networking stack hooks for CARP */
/* net/if.c */
-extern int (*carp_ioctl_p)(struct ifreq *, u_long, struct thread *);
extern int (*carp_attach_p)(struct ifaddr *, int);
extern void (*carp_detach_p)(struct ifaddr *, bool);
extern void (*carp_linkstate_p)(struct ifnet *);
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -160,23 +160,6 @@
#define CIF_PROMISC 0x00000001
};
-/* Kernel equivalent of struct carpreq, but with more fields for new features.
- * */
-struct carpkreq {
- int carpr_count;
- int carpr_vhid;
- int carpr_state;
- int carpr_advskew;
- int carpr_advbase;
- unsigned char carpr_key[CARP_KEY_LEN];
- /* Everything above this is identical to carpreq */
- struct in_addr carpr_addr;
- struct in6_addr carpr_addr6;
- carp_version_t carpr_version;
- uint8_t carpr_vrrp_priority;
- uint16_t carpr_vrrp_adv_inter;
-};
-
/*
* Brief design of carp(4).
*
@@ -2256,216 +2239,6 @@
free(cif, M_CARP);
}
-static bool
-carp_carprcp(void *arg, struct carp_softc *sc, int priv)
-{
- struct carpreq *carpr = arg;
-
- CARP_LOCK(sc);
- carpr->carpr_state = sc->sc_state;
- carpr->carpr_vhid = sc->sc_vhid;
- switch (sc->sc_version) {
- case CARP_VERSION_CARP:
- carpr->carpr_advbase = sc->sc_advbase;
- carpr->carpr_advskew = sc->sc_advskew;
- if (priv)
- bcopy(sc->sc_key, carpr->carpr_key,
- sizeof(carpr->carpr_key));
- else
- bzero(carpr->carpr_key, sizeof(carpr->carpr_key));
- break;
- case CARP_VERSION_VRRPv3:
- break;
- }
- CARP_UNLOCK(sc);
-
- return (true);
-}
-
-static int
-carp_ioctl_set(if_t ifp, struct carpkreq *carpr)
-{
- struct epoch_tracker et;
- struct carp_softc *sc = NULL;
- int error = 0;
-
- if (carpr->carpr_vhid <= 0 || carpr->carpr_vhid > CARP_MAXVHID)
- return (EINVAL);
-
- switch (carpr->carpr_version) {
- case CARP_VERSION_CARP:
- if (carpr->carpr_advbase != 0 && (carpr->carpr_advbase > 255 ||
- carpr->carpr_advbase < CARP_DFLTINTV))
- return (EINVAL);
- if (carpr->carpr_advskew < 0 || carpr->carpr_advskew >= 255)
- return (EINVAL);
- break;
- case CARP_VERSION_VRRPv3:
- /* XXXGL: shouldn't we check anything? */
- break;
- default:
- return (EINVAL);
- }
-
- if (ifp->if_carp) {
- IFNET_FOREACH_CARP(ifp, sc)
- if (sc->sc_vhid == carpr->carpr_vhid)
- break;
- }
-
- if (sc == NULL)
- sc = carp_alloc(ifp, carpr->carpr_version, carpr->carpr_vhid);
- else if (sc->sc_version != carpr->carpr_version)
- return (EINVAL);
-
- CARP_LOCK(sc);
- switch (sc->sc_version) {
- case CARP_VERSION_CARP:
- if (carpr->carpr_advbase != 0)
- sc->sc_advbase = carpr->carpr_advbase;
- sc->sc_advskew = carpr->carpr_advskew;
- if (carpr->carpr_addr.s_addr != INADDR_ANY)
- sc->sc_carpaddr = carpr->carpr_addr;
- if (!IN6_IS_ADDR_UNSPECIFIED(&carpr->carpr_addr6)) {
- memcpy(&sc->sc_carpaddr6, &carpr->carpr_addr6,
- sizeof(sc->sc_carpaddr6));
- }
- if (carpr->carpr_key[0] != '\0') {
- bcopy(carpr->carpr_key, sc->sc_key, sizeof(sc->sc_key));
- carp_hmac_prepare(sc);
- }
- break;
- case CARP_VERSION_VRRPv3:
- if (carpr->carpr_vrrp_priority != 0)
- sc->sc_vrrp_prio = carpr->carpr_vrrp_priority;
- if (carpr->carpr_vrrp_adv_inter)
- sc->sc_vrrp_adv_inter = carpr->carpr_vrrp_adv_inter;
- break;
- }
-
- if (sc->sc_state != INIT &&
- carpr->carpr_state != sc->sc_state) {
- switch (carpr->carpr_state) {
- case BACKUP:
- callout_stop(&sc->sc_ad_tmo);
- carp_set_state(sc, BACKUP,
- "user requested via ifconfig");
- carp_setrun(sc, 0);
- carp_delroute(sc);
- break;
- case MASTER:
- NET_EPOCH_ENTER(et);
- carp_master_down_locked(sc,
- "user requested via ifconfig");
- NET_EPOCH_EXIT(et);
- break;
- default:
- break;
- }
- }
- CARP_UNLOCK(sc);
-
- return (error);
-}
-
-static int
-carp_ioctl_get(if_t ifp, struct ucred *cred, struct carpreq *carpr,
- bool (*outfn)(void *, struct carp_softc *, int), void *arg)
-{
- int priveleged;
- struct carp_softc *sc;
-
- if (carpr->carpr_vhid < 0 || carpr->carpr_vhid > CARP_MAXVHID)
- return (EINVAL);
- if (carpr->carpr_count < 1)
- return (EMSGSIZE);
- if (ifp->if_carp == NULL)
- return (ENOENT);
-
- priveleged = (priv_check_cred(cred, PRIV_NETINET_CARP) == 0);
- if (carpr->carpr_vhid != 0) {
- IFNET_FOREACH_CARP(ifp, sc)
- if (sc->sc_vhid == carpr->carpr_vhid)
- break;
- if (sc == NULL)
- return (ENOENT);
-
- if (! outfn(arg, sc, priveleged))
- return (ENOMEM);
- carpr->carpr_count = 1;
- } else {
- int count;
-
- count = 0;
- IFNET_FOREACH_CARP(ifp, sc)
- count++;
-
- if (count > carpr->carpr_count)
- return (EMSGSIZE);
-
- IFNET_FOREACH_CARP(ifp, sc) {
- if (! outfn(arg, sc, priveleged))
- return (ENOMEM);
- carpr->carpr_count = count;
- }
- }
-
- return (0);
-}
-
-int
-carp_ioctl(struct ifreq *ifr, u_long cmd, struct thread *td)
-{
- struct carpreq carpr;
- struct carpkreq carprk = {
- .carpr_version = CARP_VERSION_CARP,
- };
- struct ifnet *ifp;
- int error = 0;
-
- if ((error = copyin(ifr_data_get_ptr(ifr), &carpr, sizeof carpr)))
- return (error);
-
- ifp = ifunit_ref(ifr->ifr_name);
- if ((error = carp_is_supported_if(ifp)) != 0)
- goto out;
-
- if ((ifp->if_flags & IFF_MULTICAST) == 0) {
- error = EADDRNOTAVAIL;
- goto out;
- }
-
- sx_xlock(&carp_sx);
- switch (cmd) {
- case SIOCSVH:
- if ((error = priv_check(td, PRIV_NETINET_CARP)))
- break;
-
- memcpy(&carprk, &carpr, sizeof(carpr));
- error = carp_ioctl_set(ifp, &carprk);
- break;
-
- case SIOCGVH:
- error = carp_ioctl_get(ifp, td->td_ucred, &carpr,
- carp_carprcp, &carpr);
- if (error == 0) {
- error = copyout(&carpr,
- (char *)ifr_data_get_ptr(ifr),
- carpr.carpr_count * sizeof(carpr));
- }
- break;
- default:
- error = EINVAL;
- }
- sx_xunlock(&carp_sx);
-
-out:
- if (ifp != NULL)
- if_rele(ifp);
-
- return (error);
-}
-
static int
carp_get_vhid(struct ifaddr *ifa)
{
@@ -2757,67 +2530,6 @@
return (0);
}
-struct carp_nl_send_args {
- struct nlmsghdr *hdr;
- struct nl_pstate *npt;
-};
-
-static bool
-carp_nl_send(void *arg, struct carp_softc *sc, int priv)
-{
- struct carp_nl_send_args *nlsa = arg;
- struct nlmsghdr *hdr = nlsa->hdr;
- struct nl_pstate *npt = nlsa->npt;
- struct nl_writer *nw = npt->nw;
- struct genlmsghdr *ghdr_new;
-
- if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
- nlmsg_abort(nw);
- return (false);
- }
-
- ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
- if (ghdr_new == NULL) {
- nlmsg_abort(nw);
- return (false);
- }
-
- ghdr_new->cmd = CARP_NL_CMD_GET;
- ghdr_new->version = 0;
- ghdr_new->reserved = 0;
-
- CARP_LOCK(sc);
-
- nlattr_add_u32(nw, CARP_NL_VHID, sc->sc_vhid);
- nlattr_add_u32(nw, CARP_NL_STATE, sc->sc_state);
- nlattr_add_u8(nw, CARP_NL_VERSION, sc->sc_version);
- switch (sc->sc_version) {
- case CARP_VERSION_CARP:
- nlattr_add_s32(nw, CARP_NL_ADVBASE, sc->sc_advbase);
- nlattr_add_s32(nw, CARP_NL_ADVSKEW, sc->sc_advskew);
- nlattr_add_in_addr(nw, CARP_NL_ADDR, &sc->sc_carpaddr);
- nlattr_add_in6_addr(nw, CARP_NL_ADDR6, &sc->sc_carpaddr6);
- if (priv)
- nlattr_add(nw, CARP_NL_KEY, sizeof(sc->sc_key),
- sc->sc_key);
- break;
- case CARP_VERSION_VRRPv3:
- nlattr_add_u8(nw, CARP_NL_VRRP_PRIORITY, sc->sc_vrrp_prio);
- nlattr_add_u16(nw, CARP_NL_VRRP_ADV_INTER,
- sc->sc_vrrp_adv_inter);
- break;
- }
-
- CARP_UNLOCK(sc);
-
- if (! nlmsg_end(nw)) {
- nlmsg_abort(nw);
- return (false);
- }
-
- return (true);
-}
-
struct nl_carp_parsed {
unsigned int ifindex;
char *ifname;
@@ -2856,16 +2568,20 @@
carp_nl_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
struct nl_carp_parsed attrs = { };
- struct carp_nl_send_args args;
- struct carpreq carpr = { };
struct epoch_tracker et;
+ struct nl_writer *nw = npt->nw;
+ struct carp_softc *sc;
if_t ifp = NULL;
int error;
+ bool privileged;
error = nl_parse_nlmsg(hdr, &carp_parser, npt, &attrs);
if (error != 0)
return (error);
+ if (attrs.vhid < 0 || attrs.vhid > CARP_MAXVHID)
+ return (EINVAL);
+
NET_EPOCH_ENTER(et);
if (attrs.ifname != NULL)
ifp = ifunit_ref(attrs.ifname);
@@ -2876,19 +2592,72 @@
if ((error = carp_is_supported_if(ifp)) != 0)
goto out;
- hdr->nlmsg_flags |= NLM_F_MULTI;
- args.hdr = hdr;
- args.npt = npt;
+ if (ifp->if_carp == NULL) {
+ error = ENOENT;
+ goto out;
+ }
- carpr.carpr_vhid = attrs.vhid;
- carpr.carpr_count = CARP_MAXVHID;
+ hdr->nlmsg_flags |= NLM_F_MULTI;
+ privileged = (priv_check_cred(nlp_get_cred(npt->nlp),
+ PRIV_NETINET_CARP) == 0);
sx_xlock(&carp_sx);
- error = carp_ioctl_get(ifp, nlp_get_cred(npt->nlp), &carpr,
- carp_nl_send, &args);
+ IFNET_FOREACH_CARP(ifp, sc) {
+ struct genlmsghdr *ghdr_new;
+
+ if (attrs.vhid != 0 && attrs.vhid != sc->sc_vhid)
+ continue;
+
+ if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr))) {
+ nlmsg_abort(nw);
+ error = ENOMEM;
+ break;
+ }
+
+ ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
+ if (ghdr_new == NULL) {
+ nlmsg_abort(nw);
+ error = ENOMEM;
+ break;
+ }
+
+ ghdr_new->cmd = CARP_NL_CMD_GET;
+ ghdr_new->version = 0;
+ ghdr_new->reserved = 0;
+
+ CARP_LOCK(sc);
+ nlattr_add_u32(nw, CARP_NL_VHID, sc->sc_vhid);
+ nlattr_add_u32(nw, CARP_NL_STATE, sc->sc_state);
+ nlattr_add_u8(nw, CARP_NL_VERSION, sc->sc_version);
+ switch (sc->sc_version) {
+ case CARP_VERSION_CARP:
+ nlattr_add_s32(nw, CARP_NL_ADVBASE, sc->sc_advbase);
+ nlattr_add_s32(nw, CARP_NL_ADVSKEW, sc->sc_advskew);
+ nlattr_add_in_addr(nw, CARP_NL_ADDR, &sc->sc_carpaddr);
+ nlattr_add_in6_addr(nw, CARP_NL_ADDR6,
+ &sc->sc_carpaddr6);
+ if (privileged)
+ nlattr_add(nw, CARP_NL_KEY, sizeof(sc->sc_key),
+ sc->sc_key);
+ break;
+ case CARP_VERSION_VRRPv3:
+ nlattr_add_u8(nw, CARP_NL_VRRP_PRIORITY,
+ sc->sc_vrrp_prio);
+ nlattr_add_u16(nw, CARP_NL_VRRP_ADV_INTER,
+ sc->sc_vrrp_adv_inter);
+ break;
+ }
+ CARP_UNLOCK(sc);
+
+ if (! nlmsg_end(nw)) {
+ nlmsg_abort(nw);
+ error = ENOMEM;
+ break;
+ }
+ }
sx_xunlock(&carp_sx);
- if (! nlmsg_end_dump(npt->nw, error, hdr))
+ if (! nlmsg_end_dump(nw, error, hdr))
error = ENOMEM;
out:
@@ -2902,8 +2671,8 @@
carp_nl_set(struct nlmsghdr *hdr, struct nl_pstate *npt)
{
struct nl_carp_parsed attrs = { };
- struct carpkreq carpr;
struct epoch_tracker et;
+ struct carp_softc *sc;
if_t ifp = NULL;
int error;
@@ -2949,26 +2718,66 @@
goto out;
}
- carpr.carpr_count = 1;
- carpr.carpr_vhid = attrs.vhid;
- carpr.carpr_state = attrs.state;
- carpr.carpr_version = attrs.version;
- switch (attrs.version) {
+ sx_xlock(&carp_sx);
+ if (ifp->if_carp) {
+ IFNET_FOREACH_CARP(ifp, sc)
+ if (sc->sc_vhid == attrs.vhid)
+ break;
+ } else
+ sc = NULL;
+ if (sc == NULL)
+ sc = carp_alloc(ifp, attrs.version, attrs.vhid);
+ else if (sc->sc_version != attrs.version) {
+ sx_xunlock(&carp_sx);
+ error = EINVAL;
+ goto out;
+ }
+
+ CARP_LOCK(sc);
+ switch (sc->sc_version) {
case CARP_VERSION_CARP:
- carpr.carpr_advbase = attrs.advbase;
- carpr.carpr_advskew = attrs.advskew;
- carpr.carpr_addr = attrs.addr;
- carpr.carpr_addr6 = attrs.addr6;
- memcpy(&carpr.carpr_key, &attrs.key, sizeof(attrs.key));
+ if (attrs.advbase != 0)
+ sc->sc_advbase = attrs.advbase;
+ sc->sc_advskew = attrs.advskew;
+ if (attrs.addr.s_addr != INADDR_ANY)
+ sc->sc_carpaddr = attrs.addr;
+ if (!IN6_IS_ADDR_UNSPECIFIED(&attrs.addr6)) {
+ memcpy(&sc->sc_carpaddr6, &attrs.addr6,
+ sizeof(sc->sc_carpaddr6));
+ }
+ if (attrs.key[0] != '\0') {
+ bcopy(attrs.key, sc->sc_key, sizeof(sc->sc_key));
+ carp_hmac_prepare(sc);
+ }
break;
case CARP_VERSION_VRRPv3:
- carpr.carpr_vrrp_priority = attrs.vrrp_prio;
- carpr.carpr_vrrp_adv_inter = attrs.vrrp_adv_inter;
+ if (attrs.vrrp_prio != 0)
+ sc->sc_vrrp_prio = attrs.vrrp_prio;
+ if (attrs.vrrp_adv_inter)
+ sc->sc_vrrp_adv_inter = attrs.vrrp_adv_inter;
break;
}
- sx_xlock(&carp_sx);
- error = carp_ioctl_set(ifp, &carpr);
+ if (sc->sc_state != INIT && sc->sc_state != attrs.state) {
+ switch (attrs.state) {
+ case BACKUP:
+ callout_stop(&sc->sc_ad_tmo);
+ carp_set_state(sc, BACKUP,
+ "user requested via ifconfig");
+ carp_setrun(sc, 0);
+ carp_delroute(sc);
+ break;
+ case MASTER:
+ NET_EPOCH_ENTER(et);
+ carp_master_down_locked(sc,
+ "user requested via ifconfig");
+ NET_EPOCH_EXIT(et);
+ break;
+ default:
+ break;
+ }
+ }
+ CARP_UNLOCK(sc);
sx_xunlock(&carp_sx);
out:
@@ -3035,7 +2844,6 @@
carp_iamatch6_p = NULL;
carp_macmatch6_p = NULL;
#endif
- carp_ioctl_p = NULL;
carp_attach_p = NULL;
carp_detach_p = NULL;
carp_get_vhid_p = NULL;
@@ -3070,7 +2878,6 @@
carp_forus_p = carp_forus;
carp_output_p = carp_output;
carp_linkstate_p = carp_linkstate;
- carp_ioctl_p = carp_ioctl;
carp_attach_p = carp_attach;
carp_detach_p = carp_detach;
carp_demote_adj_p = carp_demote_adj;
diff --git a/sys/sys/param.h b/sys/sys/param.h
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -74,7 +74,7 @@
* cannot include sys/param.h and should only be updated here.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1600012
+#define __FreeBSD_version 1600013
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jun 25, 3:57 AM (19 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34303448
Default Alt Text
D55804.id173538.diff (14 KB)
Attached To
Mode
D55804: carp: retire ioctl(2) API
Attached
Detach File
Event Timeline
Log In to Comment