Page MenuHomeFreeBSD

D55804.id173538.diff
No OneTemporary

D55804.id173538.diff

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

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)

Event Timeline