1
|
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
|
2
|
index 97e610d..b90dee8 100644
|
3
|
--- a/sbin/ifconfig/ifconfig.c
|
4
|
+++ b/sbin/ifconfig/ifconfig.c
|
5
|
@@ -636,6 +636,23 @@ top:
|
6
|
return(0);
|
7
|
}
|
8
|
|
9
|
+static void
|
10
|
+setaddrfirst(const char *addr, int dummy __unused, int s,
|
11
|
+ const struct afswtch *afp)
|
12
|
+{
|
13
|
+
|
14
|
+ if (afp == NULL)
|
15
|
+ err(2, "No address family");
|
16
|
+ if (afp->af_getaddr == NULL)
|
17
|
+ err(2, "No appropriate functions from address family");
|
18
|
+ afp->af_getaddr(addr, ADDR);
|
19
|
+
|
20
|
+ strncpy(afp->af_addreq, name, sizeof ifr.ifr_name);
|
21
|
+ printf("Interface name: %s, socket %d, addr %s\n", name, s, addr);
|
22
|
+ if (ioctl(s, SIOCORDERIFADDR, afp->af_addreq) < 0)
|
23
|
+ err(1, "SIOCORDERIFADDR");
|
24
|
+}
|
25
|
+
|
26
|
/*ARGSUSED*/
|
27
|
static void
|
28
|
setifaddr(const char *addr, int param, int s, const struct afswtch *afp)
|
29
|
@@ -1229,6 +1246,7 @@ static struct cmd basic_cmds[] = {
|
30
|
DEF_CMD("noicmp", IFF_LINK1, setifflags),
|
31
|
DEF_CMD_ARG("mtu", setifmtu),
|
32
|
DEF_CMD_ARG("name", setifname),
|
33
|
+ DEF_CMD_ARG("setfirst", setaddrfirst),
|
34
|
};
|
35
|
|
36
|
static __constructor void
|
37
|
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
|
38
|
index 6b71607..e87a098 100644
|
39
|
--- a/sys/netinet/in.c
|
40
|
+++ b/sys/netinet/in.c
|
41
|
@@ -315,6 +315,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
|
42
|
* Security checks before we get involved in any work.
|
43
|
*/
|
44
|
switch (cmd) {
|
45
|
+ case SIOCORDERIFADDR:
|
46
|
case SIOCAIFADDR:
|
47
|
if (td != NULL) {
|
48
|
error = priv_check(td, PRIV_NET_ADDIFADDR);
|
49
|
@@ -374,6 +375,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
|
50
|
|
51
|
error = 0;
|
52
|
switch (cmd) {
|
53
|
+ case SIOCORDERIFADDR:
|
54
|
case SIOCAIFADDR:
|
55
|
case SIOCDIFADDR:
|
56
|
if (ifra->ifra_addr.sin_family == AF_INET) {
|
57
|
@@ -399,10 +401,17 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
|
58
|
goto out;
|
59
|
}
|
60
|
}
|
61
|
- if (cmd == SIOCDIFADDR && ia == NULL) {
|
62
|
+ if ((cmd == SIOCDIFADDR || cmd == SIOCORDERIFADDR) && ia == NULL) {
|
63
|
error = EADDRNOTAVAIL;
|
64
|
goto out;
|
65
|
}
|
66
|
+ if (cmd == SIOCORDERIFADDR && ia != NULL) {
|
67
|
+ IF_ADDR_WLOCK(ifp);
|
68
|
+ TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
|
69
|
+ TAILQ_INSERT_AFTER(&ifp->if_addrhead, TAILQ_FIRST(&ifp->if_addrhead), &ia->ia_ifa, ifa_link);
|
70
|
+ IF_ADDR_WUNLOCK(ifp);
|
71
|
+ goto out;
|
72
|
+ }
|
73
|
if (ia == NULL) {
|
74
|
ia = (struct in_ifaddr *)
|
75
|
malloc(sizeof *ia, M_IFADDR, M_NOWAIT |
|
76
|
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
|
77
|
index 17ee232..30acf87 100644
|
78
|
--- a/sys/sys/sockio.h
|
79
|
+++ b/sys/sys/sockio.h
|
80
|
@@ -127,5 +127,6 @@
|
81
|
#define SIOCGIFGROUP _IOWR('i', 136, struct ifgroupreq) /* get ifgroups */
|
82
|
#define SIOCDIFGROUP _IOW('i', 137, struct ifgroupreq) /* delete ifgroup */
|
83
|
#define SIOCGIFGMEMB _IOWR('i', 138, struct ifgroupreq) /* get members */
|
84
|
+#define SIOCORDERIFADDR _IOWR('i', 139, struct ifaliasreq) /* reorder interface */
|
85
|
|
86
|
#endif /* !_SYS_SOCKIO_H_ */
|