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 char lacpbuf
[120]; /* LACP peer '[(a,a,a),(p,p,p)]' */
29 setlaggport(const char *val
, int d
, int s
, const struct afswtch
*afp
)
31 struct lagg_reqport rp
;
33 bzero(&rp
, sizeof(rp
));
34 strlcpy(rp
.rp_ifname
, name
, sizeof(rp
.rp_ifname
));
35 strlcpy(rp
.rp_portname
, val
, sizeof(rp
.rp_portname
));
38 * Do not exit with an error here. Doing so permits a failed NIC
39 * to take down an entire lagg.
41 * Don't error at all if the port is already in the lagg.
43 if (ioctl(s
, SIOCSLAGGPORT
, &rp
) && errno
!= EEXIST
) {
44 warnx("%s %s: SIOCSLAGGPORT: %s",
45 name
, val
, strerror(errno
));
51 unsetlaggport(const char *val
, int d
, int s
, const struct afswtch
*afp
)
53 struct lagg_reqport rp
;
55 bzero(&rp
, sizeof(rp
));
56 strlcpy(rp
.rp_ifname
, name
, sizeof(rp
.rp_ifname
));
57 strlcpy(rp
.rp_portname
, val
, sizeof(rp
.rp_portname
));
59 if (ioctl(s
, SIOCSLAGGDELPORT
, &rp
))
60 err(1, "SIOCSLAGGDELPORT");
64 setlaggproto(const char *val
, int d
, int s
, const struct afswtch
*afp
)
66 struct lagg_protos lpr
[] = LAGG_PROTOS
;
67 struct lagg_reqall ra
;
70 bzero(&ra
, sizeof(ra
));
71 ra
.ra_proto
= LAGG_PROTO_MAX
;
73 for (i
= 0; i
< nitems(lpr
); i
++) {
74 if (strcmp(val
, lpr
[i
].lpr_name
) == 0) {
75 ra
.ra_proto
= lpr
[i
].lpr_proto
;
79 if (ra
.ra_proto
== LAGG_PROTO_MAX
)
80 errx(1, "Invalid aggregation protocol: %s", val
);
82 strlcpy(ra
.ra_ifname
, name
, sizeof(ra
.ra_ifname
));
83 if (ioctl(s
, SIOCSLAGG
, &ra
) != 0)
88 setlagghash(const char *val
, int d
, int s
, const struct afswtch
*afp
)
90 struct lagg_reqflags rf
;
91 char *str
, *tmp
, *tok
;
95 str
= tmp
= strdup(val
);
96 while ((tok
= strsep(&tmp
, ",")) != NULL
) {
97 if (strcmp(tok
, "l2") == 0)
98 rf
.rf_flags
|= LAGG_F_HASHL2
;
99 else if (strcmp(tok
, "l3") == 0)
100 rf
.rf_flags
|= LAGG_F_HASHL3
;
101 else if (strcmp(tok
, "l4") == 0)
102 rf
.rf_flags
|= LAGG_F_HASHL4
;
104 errx(1, "Invalid lagghash option: %s", tok
);
107 if (rf
.rf_flags
== 0)
108 errx(1, "No lagghash options supplied");
110 strlcpy(rf
.rf_ifname
, name
, sizeof(rf
.rf_ifname
));
111 if (ioctl(s
, SIOCSLAGGHASH
, &rf
))
112 err(1, "SIOCSLAGGHASH");
116 lacp_format_mac(const uint8_t *mac
, char *buf
, size_t buflen
)
118 snprintf(buf
, buflen
, "%02X-%02X-%02X-%02X-%02X-%02X",
119 (int)mac
[0], (int)mac
[1], (int)mac
[2], (int)mac
[3],
120 (int)mac
[4], (int)mac
[5]);
126 lacp_format_peer(struct lacp_opreq
*req
, const char *sep
)
131 snprintf(lacpbuf
, sizeof(lacpbuf
),
132 "[(%04X,%s,%04X,%04X,%04X),%s(%04X,%s,%04X,%04X,%04X)]",
134 lacp_format_mac(req
->actor_mac
, macbuf1
, sizeof(macbuf1
)),
135 req
->actor_key
, req
->actor_portprio
, req
->actor_portno
, sep
,
137 lacp_format_mac(req
->partner_mac
, macbuf2
, sizeof(macbuf2
)),
138 req
->partner_key
, req
->partner_portprio
, req
->partner_portno
);
146 struct lagg_protos lpr
[] = LAGG_PROTOS
;
147 struct lagg_reqport rp
, rpbuf
[LAGG_MAX_PORTS
];
148 struct lagg_reqall ra
;
149 struct lagg_reqflags rf
;
150 struct lacp_opreq
*lp
;
151 const char *proto
= "<unknown>";
155 bzero(&rp
, sizeof(rp
));
156 bzero(&ra
, sizeof(ra
));
158 strlcpy(rp
.rp_ifname
, name
, sizeof(rp
.rp_ifname
));
159 strlcpy(rp
.rp_portname
, name
, sizeof(rp
.rp_portname
));
161 if (ioctl(s
, SIOCGLAGGPORT
, &rp
) == 0)
164 strlcpy(ra
.ra_ifname
, name
, sizeof(ra
.ra_ifname
));
165 ra
.ra_size
= sizeof(rpbuf
);
168 strlcpy(rf
.rf_ifname
, name
, sizeof(rf
.rf_ifname
));
169 if (ioctl(s
, SIOCGLAGGFLAGS
, &rf
) != 0)
172 if (ioctl(s
, SIOCGLAGG
, &ra
) == 0) {
173 lp
= (struct lacp_opreq
*)&ra
.ra_lacpreq
;
175 for (i
= 0; i
< nitems(lpr
); i
++) {
176 if ((int)ra
.ra_proto
== lpr
[i
].lpr_proto
) {
177 proto
= lpr
[i
].lpr_name
;
182 printf("\tlaggproto %s", proto
);
183 if (rf
.rf_flags
& LAGG_F_HASHMASK
) {
184 const char *sep
= "";
186 printf(" lagghash ");
187 if (rf
.rf_flags
& LAGG_F_HASHL2
) {
191 if (rf
.rf_flags
& LAGG_F_HASHL3
) {
195 if (rf
.rf_flags
& LAGG_F_HASHL4
) {
201 printf(" laggdev %s", rp
.rp_ifname
);
203 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
204 printf("\tlag id: %s\n",
205 lacp_format_peer(lp
, "\n\t\t "));
207 for (i
= 0; i
< (size_t)ra
.ra_ports
; i
++) {
208 lp
= (struct lacp_opreq
*)&rpbuf
[i
].rp_lacpreq
;
209 printf("\tlaggport: %s ", rpbuf
[i
].rp_portname
);
210 printb("flags", rpbuf
[i
].rp_flags
, LAGG_PORT_BITS
);
211 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
212 printf(" state=%X", lp
->actor_state
);
214 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
216 lacp_format_peer(lp
, "\n\t\t "));
220 printf("\tsupported aggregation protocols:\n");
221 for (i
= 0; i
< nitems(lpr
); i
++)
222 printf("\t\tlaggproto %s\n", lpr
[i
].lpr_name
);
227 static struct cmd lagg_cmds
[] = {
228 DEF_CMD_ARG("laggport", setlaggport
),
229 DEF_CMD_ARG("-laggport", unsetlaggport
),
230 DEF_CMD_ARG("laggproto", setlaggproto
),
231 DEF_CMD_ARG("lagghash", setlagghash
),
233 static struct afswtch af_lagg
= {
234 .af_name
= "af_lagg",
236 .af_other_status
= lagg_status
,
239 static __constructor(101) void
244 for (i
= 0; i
< nitems(lagg_cmds
); i
++)
245 cmd_register(&lagg_cmds
[i
]);
246 af_register(&af_lagg
);