2 * $FreeBSD: head/sbin/ifconfig/iflagg.c 249897 2013-04-25 16:34:04Z glebius $
7 #include <sys/socket.h>
8 #include <sys/sockio.h>
11 #include <net/route.h>
12 #include <net/ethernet.h>
13 #include <net/lagg/if_lagg.h>
26 static char lacpbuf
[120]; /* LACP peer '[(a,a,a),(p,p,p)]' */
29 setlaggport(const char *val
, int d __unused
, int s
,
30 const struct afswtch
*afp __unused
)
32 struct lagg_reqport rp
;
34 memset(&rp
, 0, sizeof(rp
));
35 strlcpy(rp
.rp_ifname
, IfName
, sizeof(rp
.rp_ifname
));
36 strlcpy(rp
.rp_portname
, val
, sizeof(rp
.rp_portname
));
39 * Do not exit with an error here. Doing so permits a failed NIC
40 * to take down an entire lagg.
42 * Don't error at all if the port is already in the lagg.
44 if (ioctl(s
, SIOCSLAGGPORT
, &rp
) && errno
!= EEXIST
) {
45 warnx("%s %s: SIOCSLAGGPORT: %s",
46 IfName
, val
, strerror(errno
));
52 unsetlaggport(const char *val
, int d __unused
, int s
,
53 const struct afswtch
*afp __unused
)
55 struct lagg_reqport rp
;
57 memset(&rp
, 0, sizeof(rp
));
58 strlcpy(rp
.rp_ifname
, IfName
, sizeof(rp
.rp_ifname
));
59 strlcpy(rp
.rp_portname
, val
, sizeof(rp
.rp_portname
));
61 if (ioctl(s
, SIOCSLAGGDELPORT
, &rp
))
62 err(1, "SIOCSLAGGDELPORT");
66 setlaggproto(const char *val
, int d __unused
, int s
,
67 const struct afswtch
*afp __unused
)
69 struct lagg_protos lpr
[] = LAGG_PROTOS
;
70 struct lagg_reqall ra
;
73 memset(&ra
, 0, sizeof(ra
));
74 ra
.ra_proto
= LAGG_PROTO_MAX
;
76 for (i
= 0; i
< nitems(lpr
); i
++) {
77 if (strcmp(val
, lpr
[i
].lpr_name
) == 0) {
78 ra
.ra_proto
= lpr
[i
].lpr_proto
;
82 if (ra
.ra_proto
== LAGG_PROTO_MAX
)
83 errx(1, "Invalid aggregation protocol: %s", val
);
85 strlcpy(ra
.ra_ifname
, IfName
, sizeof(ra
.ra_ifname
));
86 if (ioctl(s
, SIOCSLAGG
, &ra
) != 0)
91 setlagghash(const char *val
, int d __unused
, int s
,
92 const struct afswtch
*afp __unused
)
94 struct lagg_reqflags rf
;
95 char *str
, *tmp
, *tok
;
98 str
= tmp
= strdup(val
);
99 while ((tok
= strsep(&tmp
, ",")) != NULL
) {
100 if (strcmp(tok
, "l2") == 0)
101 rf
.rf_flags
|= LAGG_F_HASHL2
;
102 else if (strcmp(tok
, "l3") == 0)
103 rf
.rf_flags
|= LAGG_F_HASHL3
;
104 else if (strcmp(tok
, "l4") == 0)
105 rf
.rf_flags
|= LAGG_F_HASHL4
;
107 errx(1, "Invalid lagghash option: %s", tok
);
110 if (rf
.rf_flags
== 0)
111 errx(1, "No lagghash options supplied");
113 strlcpy(rf
.rf_ifname
, IfName
, sizeof(rf
.rf_ifname
));
114 if (ioctl(s
, SIOCSLAGGHASH
, &rf
))
115 err(1, "SIOCSLAGGHASH");
119 lacp_format_mac(const uint8_t *mac
, char *buf
, size_t buflen
)
121 snprintf(buf
, buflen
, "%02X-%02X-%02X-%02X-%02X-%02X",
122 (int)mac
[0], (int)mac
[1], (int)mac
[2], (int)mac
[3],
123 (int)mac
[4], (int)mac
[5]);
129 lacp_format_peer(struct lacp_opreq
*req
, const char *sep
)
134 snprintf(lacpbuf
, sizeof(lacpbuf
),
135 "[(%04X,%s,%04X,%04X,%04X),%s(%04X,%s,%04X,%04X,%04X)]",
137 lacp_format_mac(req
->actor_mac
, macbuf1
, sizeof(macbuf1
)),
138 req
->actor_key
, req
->actor_portprio
, req
->actor_portno
, sep
,
140 lacp_format_mac(req
->partner_mac
, macbuf2
, sizeof(macbuf2
)),
141 req
->partner_key
, req
->partner_portprio
, req
->partner_portno
);
149 struct lagg_protos lpr
[] = LAGG_PROTOS
;
150 struct lagg_reqport rp
, rpbuf
[LAGG_MAX_PORTS
];
151 struct lagg_reqall ra
;
152 struct lagg_reqflags rf
;
153 struct lacp_opreq
*lp
;
154 const char *proto
= "<unknown>";
158 memset(&rp
, 0, sizeof(rp
));
159 memset(&ra
, 0, sizeof(ra
));
161 strlcpy(rp
.rp_ifname
, IfName
, sizeof(rp
.rp_ifname
));
162 strlcpy(rp
.rp_portname
, IfName
, sizeof(rp
.rp_portname
));
164 if (ioctl(s
, SIOCGLAGGPORT
, &rp
) == 0)
167 strlcpy(ra
.ra_ifname
, IfName
, sizeof(ra
.ra_ifname
));
168 ra
.ra_size
= sizeof(rpbuf
);
171 strlcpy(rf
.rf_ifname
, IfName
, sizeof(rf
.rf_ifname
));
172 if (ioctl(s
, SIOCGLAGGFLAGS
, &rf
) != 0)
175 if (ioctl(s
, SIOCGLAGG
, &ra
) == 0) {
176 lp
= (struct lacp_opreq
*)&ra
.ra_lacpreq
;
178 for (i
= 0; i
< nitems(lpr
); i
++) {
179 if ((int)ra
.ra_proto
== lpr
[i
].lpr_proto
) {
180 proto
= lpr
[i
].lpr_name
;
185 printf("\tlaggproto %s", proto
);
186 if (rf
.rf_flags
& LAGG_F_HASHMASK
) {
187 const char *sep
= "";
189 printf(" lagghash ");
190 if (rf
.rf_flags
& LAGG_F_HASHL2
) {
194 if (rf
.rf_flags
& LAGG_F_HASHL3
) {
198 if (rf
.rf_flags
& LAGG_F_HASHL4
) {
204 printf(" laggdev %s", rp
.rp_ifname
);
206 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
207 printf("\tlag id: %s\n",
208 lacp_format_peer(lp
, "\n\t\t "));
210 for (i
= 0; i
< (size_t)ra
.ra_ports
; i
++) {
211 lp
= (struct lacp_opreq
*)&rpbuf
[i
].rp_lacpreq
;
212 printf("\tlaggport: %s ", rpbuf
[i
].rp_portname
);
213 printb("flags", rpbuf
[i
].rp_flags
, LAGG_PORT_BITS
);
214 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
215 printf(" state=%X", lp
->actor_state
);
217 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
219 lacp_format_peer(lp
, "\n\t\t "));
223 printf("\tsupported aggregation protocols:\n");
224 for (i
= 0; i
< nitems(lpr
); i
++)
225 printf("\t\tlaggproto %s\n", lpr
[i
].lpr_name
);
230 static struct cmd lagg_cmds
[] = {
231 DEF_CMD_ARG("laggport", setlaggport
),
232 DEF_CMD_ARG("-laggport", unsetlaggport
),
233 DEF_CMD_ARG("laggproto", setlaggproto
),
234 DEF_CMD_ARG("lagghash", setlagghash
),
236 static struct afswtch af_lagg
= {
237 .af_name
= "af_lagg",
239 .af_other_status
= lagg_status
,
248 for (i
= 0; i
< nitems(lagg_cmds
); i
++)
249 cmd_register(&lagg_cmds
[i
]);
251 af_register(&af_lagg
);