5 static const char rcsid
[] =
6 "$FreeBSD: head/sbin/ifconfig/iflagg.c 249897 2013-04-25 16:34:04Z glebius $";
10 #include <sys/ioctl.h>
11 #include <sys/socket.h>
12 #include <sys/sockio.h>
17 #include <net/ethernet.h>
19 #include <net/lagg/if_lagg.h>
20 #include <net/route.h>
32 char lacpbuf
[120]; /* LACP peer '[(a,a,a),(p,p,p)]' */
35 setlaggport(const char *val
, int d
, int s
, const struct afswtch
*afp
)
37 struct lagg_reqport rp
;
39 bzero(&rp
, sizeof(rp
));
40 strlcpy(rp
.rp_ifname
, name
, sizeof(rp
.rp_ifname
));
41 strlcpy(rp
.rp_portname
, val
, sizeof(rp
.rp_portname
));
43 /* Don't choke if the port is already in this lagg. */
44 if (ioctl(s
, SIOCSLAGGPORT
, &rp
) && errno
!= EEXIST
)
45 err(1, "SIOCSLAGGPORT");
49 unsetlaggport(const char *val
, int d
, int s
, const struct afswtch
*afp
)
51 struct lagg_reqport rp
;
53 bzero(&rp
, sizeof(rp
));
54 strlcpy(rp
.rp_ifname
, name
, sizeof(rp
.rp_ifname
));
55 strlcpy(rp
.rp_portname
, val
, sizeof(rp
.rp_portname
));
57 if (ioctl(s
, SIOCSLAGGDELPORT
, &rp
))
58 err(1, "SIOCSLAGGDELPORT");
62 setlaggproto(const char *val
, int d
, int s
, const struct afswtch
*afp
)
64 struct lagg_protos lpr
[] = LAGG_PROTOS
;
65 struct lagg_reqall ra
;
68 bzero(&ra
, sizeof(ra
));
69 ra
.ra_proto
= LAGG_PROTO_MAX
;
71 for (i
= 0; i
< (sizeof(lpr
) / sizeof(lpr
[0])); i
++) {
72 if (strcmp(val
, lpr
[i
].lpr_name
) == 0) {
73 ra
.ra_proto
= lpr
[i
].lpr_proto
;
77 if (ra
.ra_proto
== LAGG_PROTO_MAX
)
78 errx(1, "Invalid aggregation protocol: %s", val
);
80 strlcpy(ra
.ra_ifname
, name
, sizeof(ra
.ra_ifname
));
81 if (ioctl(s
, SIOCSLAGG
, &ra
) != 0)
86 setlagghash(const char *val
, int d
, int s
, const struct afswtch
*afp
)
88 struct lagg_reqflags rf
;
89 char *str
, *tmp
, *tok
;
93 str
= tmp
= strdup(val
);
94 while ((tok
= strsep(&tmp
, ",")) != NULL
) {
95 if (strcmp(tok
, "l2") == 0)
96 rf
.rf_flags
|= LAGG_F_HASHL2
;
97 else if (strcmp(tok
, "l3") == 0)
98 rf
.rf_flags
|= LAGG_F_HASHL3
;
99 else if (strcmp(tok
, "l4") == 0)
100 rf
.rf_flags
|= LAGG_F_HASHL4
;
102 errx(1, "Invalid lagghash option: %s", tok
);
105 if (rf
.rf_flags
== 0)
106 errx(1, "No lagghash options supplied");
108 strlcpy(rf
.rf_ifname
, name
, sizeof(rf
.rf_ifname
));
109 if (ioctl(s
, SIOCSLAGGHASH
, &rf
))
110 err(1, "SIOCSLAGGHASH");
114 lacp_format_mac(const uint8_t *mac
, char *buf
, size_t buflen
)
116 snprintf(buf
, buflen
, "%02X-%02X-%02X-%02X-%02X-%02X",
117 (int)mac
[0], (int)mac
[1], (int)mac
[2], (int)mac
[3],
118 (int)mac
[4], (int)mac
[5]);
124 lacp_format_peer(struct lacp_opreq
*req
, const char *sep
)
129 snprintf(lacpbuf
, sizeof(lacpbuf
),
130 "[(%04X,%s,%04X,%04X,%04X),%s(%04X,%s,%04X,%04X,%04X)]",
132 lacp_format_mac(req
->actor_mac
, macbuf1
, sizeof(macbuf1
)),
133 req
->actor_key
, req
->actor_portprio
, req
->actor_portno
, sep
,
135 lacp_format_mac(req
->partner_mac
, macbuf2
, sizeof(macbuf2
)),
136 req
->partner_key
, req
->partner_portprio
, req
->partner_portno
);
144 struct lagg_protos lpr
[] = LAGG_PROTOS
;
145 struct lagg_reqport rp
, rpbuf
[LAGG_MAX_PORTS
];
146 struct lagg_reqall ra
;
147 struct lagg_reqflags rf
;
148 struct lacp_opreq
*lp
;
149 const char *proto
= "<unknown>";
152 bzero(&rp
, sizeof(rp
));
153 bzero(&ra
, sizeof(ra
));
155 strlcpy(rp
.rp_ifname
, name
, sizeof(rp
.rp_ifname
));
156 strlcpy(rp
.rp_portname
, name
, sizeof(rp
.rp_portname
));
158 if (ioctl(s
, SIOCGLAGGPORT
, &rp
) == 0)
161 strlcpy(ra
.ra_ifname
, name
, sizeof(ra
.ra_ifname
));
162 ra
.ra_size
= sizeof(rpbuf
);
165 strlcpy(rf
.rf_ifname
, name
, sizeof(rf
.rf_ifname
));
166 if (ioctl(s
, SIOCGLAGGFLAGS
, &rf
) != 0)
169 if (ioctl(s
, SIOCGLAGG
, &ra
) == 0) {
170 lp
= (struct lacp_opreq
*)&ra
.ra_lacpreq
;
172 for (i
= 0; i
< (sizeof(lpr
) / sizeof(lpr
[0])); i
++) {
173 if (ra
.ra_proto
== lpr
[i
].lpr_proto
) {
174 proto
= lpr
[i
].lpr_name
;
179 printf("\tlaggproto %s", proto
);
180 if (rf
.rf_flags
& LAGG_F_HASHMASK
) {
181 const char *sep
= "";
183 printf(" lagghash ");
184 if (rf
.rf_flags
& LAGG_F_HASHL2
) {
188 if (rf
.rf_flags
& LAGG_F_HASHL3
) {
192 if (rf
.rf_flags
& LAGG_F_HASHL4
) {
198 printf(" laggdev %s", rp
.rp_ifname
);
200 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
201 printf("\tlag id: %s\n",
202 lacp_format_peer(lp
, "\n\t\t "));
204 for (i
= 0; i
< ra
.ra_ports
; i
++) {
205 lp
= (struct lacp_opreq
*)&rpbuf
[i
].rp_lacpreq
;
206 printf("\tlaggport: %s ", rpbuf
[i
].rp_portname
);
207 printb("flags", rpbuf
[i
].rp_flags
, LAGG_PORT_BITS
);
208 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
209 printf(" state=%X", lp
->actor_state
);
211 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
213 lacp_format_peer(lp
, "\n\t\t "));
217 printf("\tsupported aggregation protocols:\n");
218 for (i
= 0; i
< (sizeof(lpr
) / sizeof(lpr
[0])); i
++)
219 printf("\t\tlaggproto %s\n", lpr
[i
].lpr_name
);
224 static struct cmd lagg_cmds
[] = {
225 DEF_CMD_ARG("laggport", setlaggport
),
226 DEF_CMD_ARG("-laggport", unsetlaggport
),
227 DEF_CMD_ARG("laggproto", setlaggproto
),
228 DEF_CMD_ARG("lagghash", setlagghash
),
230 static struct afswtch af_lagg
= {
231 .af_name
= "af_lagg",
233 .af_other_status
= lagg_status
,
236 static __constructor(101) void
239 #define N(a) (sizeof(a) / sizeof(a[0]))
242 for (i
= 0; i
< N(lagg_cmds
); i
++)
243 cmd_register(&lagg_cmds
[i
]);
244 af_register(&af_lagg
);