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>
13 #include <net/ethernet.h>
15 #include <net/lagg/if_lagg.h>
16 #include <net/route.h>
28 char lacpbuf
[120]; /* LACP peer '[(a,a,a),(p,p,p)]' */
31 setlaggport(const char *val
, int d
, int s
, const struct afswtch
*afp
)
33 struct lagg_reqport rp
;
35 bzero(&rp
, sizeof(rp
));
36 strlcpy(rp
.rp_ifname
, name
, sizeof(rp
.rp_ifname
));
37 strlcpy(rp
.rp_portname
, val
, sizeof(rp
.rp_portname
));
39 /* Don't choke if the port is already in this lagg. */
40 if (ioctl(s
, SIOCSLAGGPORT
, &rp
) && errno
!= EEXIST
)
41 err(1, "SIOCSLAGGPORT");
45 unsetlaggport(const char *val
, int d
, int s
, const struct afswtch
*afp
)
47 struct lagg_reqport rp
;
49 bzero(&rp
, sizeof(rp
));
50 strlcpy(rp
.rp_ifname
, name
, sizeof(rp
.rp_ifname
));
51 strlcpy(rp
.rp_portname
, val
, sizeof(rp
.rp_portname
));
53 if (ioctl(s
, SIOCSLAGGDELPORT
, &rp
))
54 err(1, "SIOCSLAGGDELPORT");
58 setlaggproto(const char *val
, int d
, int s
, const struct afswtch
*afp
)
60 struct lagg_protos lpr
[] = LAGG_PROTOS
;
61 struct lagg_reqall ra
;
64 bzero(&ra
, sizeof(ra
));
65 ra
.ra_proto
= LAGG_PROTO_MAX
;
67 for (i
= 0; i
< (NELEM(lpr
)); i
++) {
68 if (strcmp(val
, lpr
[i
].lpr_name
) == 0) {
69 ra
.ra_proto
= lpr
[i
].lpr_proto
;
73 if (ra
.ra_proto
== LAGG_PROTO_MAX
)
74 errx(1, "Invalid aggregation protocol: %s", val
);
76 strlcpy(ra
.ra_ifname
, name
, sizeof(ra
.ra_ifname
));
77 if (ioctl(s
, SIOCSLAGG
, &ra
) != 0)
82 setlagghash(const char *val
, int d
, int s
, const struct afswtch
*afp
)
84 struct lagg_reqflags rf
;
85 char *str
, *tmp
, *tok
;
89 str
= tmp
= strdup(val
);
90 while ((tok
= strsep(&tmp
, ",")) != NULL
) {
91 if (strcmp(tok
, "l2") == 0)
92 rf
.rf_flags
|= LAGG_F_HASHL2
;
93 else if (strcmp(tok
, "l3") == 0)
94 rf
.rf_flags
|= LAGG_F_HASHL3
;
95 else if (strcmp(tok
, "l4") == 0)
96 rf
.rf_flags
|= LAGG_F_HASHL4
;
98 errx(1, "Invalid lagghash option: %s", tok
);
101 if (rf
.rf_flags
== 0)
102 errx(1, "No lagghash options supplied");
104 strlcpy(rf
.rf_ifname
, name
, sizeof(rf
.rf_ifname
));
105 if (ioctl(s
, SIOCSLAGGHASH
, &rf
))
106 err(1, "SIOCSLAGGHASH");
110 lacp_format_mac(const uint8_t *mac
, char *buf
, size_t buflen
)
112 snprintf(buf
, buflen
, "%02X-%02X-%02X-%02X-%02X-%02X",
113 (int)mac
[0], (int)mac
[1], (int)mac
[2], (int)mac
[3],
114 (int)mac
[4], (int)mac
[5]);
120 lacp_format_peer(struct lacp_opreq
*req
, const char *sep
)
125 snprintf(lacpbuf
, sizeof(lacpbuf
),
126 "[(%04X,%s,%04X,%04X,%04X),%s(%04X,%s,%04X,%04X,%04X)]",
128 lacp_format_mac(req
->actor_mac
, macbuf1
, sizeof(macbuf1
)),
129 req
->actor_key
, req
->actor_portprio
, req
->actor_portno
, sep
,
131 lacp_format_mac(req
->partner_mac
, macbuf2
, sizeof(macbuf2
)),
132 req
->partner_key
, req
->partner_portprio
, req
->partner_portno
);
140 struct lagg_protos lpr
[] = LAGG_PROTOS
;
141 struct lagg_reqport rp
, rpbuf
[LAGG_MAX_PORTS
];
142 struct lagg_reqall ra
;
143 struct lagg_reqflags rf
;
144 struct lacp_opreq
*lp
;
145 const char *proto
= "<unknown>";
148 bzero(&rp
, sizeof(rp
));
149 bzero(&ra
, sizeof(ra
));
151 strlcpy(rp
.rp_ifname
, name
, sizeof(rp
.rp_ifname
));
152 strlcpy(rp
.rp_portname
, name
, sizeof(rp
.rp_portname
));
154 if (ioctl(s
, SIOCGLAGGPORT
, &rp
) == 0)
157 strlcpy(ra
.ra_ifname
, name
, sizeof(ra
.ra_ifname
));
158 ra
.ra_size
= sizeof(rpbuf
);
161 strlcpy(rf
.rf_ifname
, name
, sizeof(rf
.rf_ifname
));
162 if (ioctl(s
, SIOCGLAGGFLAGS
, &rf
) != 0)
165 if (ioctl(s
, SIOCGLAGG
, &ra
) == 0) {
166 lp
= (struct lacp_opreq
*)&ra
.ra_lacpreq
;
168 for (i
= 0; i
< (NELEM(lpr
)); i
++) {
169 if (ra
.ra_proto
== lpr
[i
].lpr_proto
) {
170 proto
= lpr
[i
].lpr_name
;
175 printf("\tlaggproto %s", proto
);
176 if (rf
.rf_flags
& LAGG_F_HASHMASK
) {
177 const char *sep
= "";
179 printf(" lagghash ");
180 if (rf
.rf_flags
& LAGG_F_HASHL2
) {
184 if (rf
.rf_flags
& LAGG_F_HASHL3
) {
188 if (rf
.rf_flags
& LAGG_F_HASHL4
) {
194 printf(" laggdev %s", rp
.rp_ifname
);
196 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
197 printf("\tlag id: %s\n",
198 lacp_format_peer(lp
, "\n\t\t "));
200 for (i
= 0; i
< ra
.ra_ports
; i
++) {
201 lp
= (struct lacp_opreq
*)&rpbuf
[i
].rp_lacpreq
;
202 printf("\tlaggport: %s ", rpbuf
[i
].rp_portname
);
203 printb("flags", rpbuf
[i
].rp_flags
, LAGG_PORT_BITS
);
204 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
205 printf(" state=%X", lp
->actor_state
);
207 if (verbose
&& ra
.ra_proto
== LAGG_PROTO_LACP
)
209 lacp_format_peer(lp
, "\n\t\t "));
213 printf("\tsupported aggregation protocols:\n");
214 for (i
= 0; i
< (NELEM(lpr
)); i
++)
215 printf("\t\tlaggproto %s\n", lpr
[i
].lpr_name
);
220 static struct cmd lagg_cmds
[] = {
221 DEF_CMD_ARG("laggport", setlaggport
),
222 DEF_CMD_ARG("-laggport", unsetlaggport
),
223 DEF_CMD_ARG("laggproto", setlaggproto
),
224 DEF_CMD_ARG("lagghash", setlagghash
),
226 static struct afswtch af_lagg
= {
227 .af_name
= "af_lagg",
229 .af_other_status
= lagg_status
,
232 static __constructor(101) void
235 #define N(a) (sizeof(a) / sizeof(a[0]))
238 for (i
= 0; i
< N(lagg_cmds
); i
++)
239 cmd_register(&lagg_cmds
[i
]);
240 af_register(&af_lagg
);