@@ -72,7 +72,7 @@ struct options {
72
72
struct option_cmsg_u32 tclass ;
73
73
struct option_cmsg_u32 hlimit ;
74
74
struct option_cmsg_u32 exthdr ;
75
- } v6 ;
75
+ } cmsg ;
76
76
} opt = {
77
77
.size = 13 ,
78
78
.num_pkt = 1 ,
@@ -104,10 +104,10 @@ static void __attribute__((noreturn)) cs_usage(const char *bin)
104
104
"\t\t-t Enable time stamp reporting\n"
105
105
"\t\t-f val Set don't fragment via cmsg\n"
106
106
"\t\t-F val Set don't fragment via setsockopt\n"
107
- "\t\t-c val Set TCLASS via cmsg\n"
108
- "\t\t-C val Set TCLASS via setsockopt\n"
109
- "\t\t-l val Set HOPLIMIT via cmsg\n"
110
- "\t\t-L val Set HOPLIMIT via setsockopt\n"
107
+ "\t\t-c val Set TOS/ TCLASS via cmsg\n"
108
+ "\t\t-C val Set TOS/ TCLASS via setsockopt\n"
109
+ "\t\t-l val Set TTL/ HOPLIMIT via cmsg\n"
110
+ "\t\t-L val Set TTL/ HOPLIMIT via setsockopt\n"
111
111
"\t\t-H type Add an IPv6 header option\n"
112
112
"\t\t (h = HOP; d = DST; r = RTDST)"
113
113
"" );
@@ -169,37 +169,37 @@ static void cs_parse_args(int argc, char *argv[])
169
169
opt .ts .ena = true;
170
170
break ;
171
171
case 'f' :
172
- opt .v6 .dontfrag .ena = true;
173
- opt .v6 .dontfrag .val = atoi (optarg );
172
+ opt .cmsg .dontfrag .ena = true;
173
+ opt .cmsg .dontfrag .val = atoi (optarg );
174
174
break ;
175
175
case 'F' :
176
176
opt .sockopt .dontfrag = atoi (optarg );
177
177
break ;
178
178
case 'c' :
179
- opt .v6 .tclass .ena = true;
180
- opt .v6 .tclass .val = atoi (optarg );
179
+ opt .cmsg .tclass .ena = true;
180
+ opt .cmsg .tclass .val = atoi (optarg );
181
181
break ;
182
182
case 'C' :
183
183
opt .sockopt .tclass = atoi (optarg );
184
184
break ;
185
185
case 'l' :
186
- opt .v6 .hlimit .ena = true;
187
- opt .v6 .hlimit .val = atoi (optarg );
186
+ opt .cmsg .hlimit .ena = true;
187
+ opt .cmsg .hlimit .val = atoi (optarg );
188
188
break ;
189
189
case 'L' :
190
190
opt .sockopt .hlimit = atoi (optarg );
191
191
break ;
192
192
case 'H' :
193
- opt .v6 .exthdr .ena = true;
193
+ opt .cmsg .exthdr .ena = true;
194
194
switch (optarg [0 ]) {
195
195
case 'h' :
196
- opt .v6 .exthdr .val = IPV6_HOPOPTS ;
196
+ opt .cmsg .exthdr .val = IPV6_HOPOPTS ;
197
197
break ;
198
198
case 'd' :
199
- opt .v6 .exthdr .val = IPV6_DSTOPTS ;
199
+ opt .cmsg .exthdr .val = IPV6_DSTOPTS ;
200
200
break ;
201
201
case 'r' :
202
- opt .v6 .exthdr .val = IPV6_RTHDRDSTOPTS ;
202
+ opt .cmsg .exthdr .val = IPV6_RTHDRDSTOPTS ;
203
203
break ;
204
204
default :
205
205
printf ("Error: hdr type: %s\n" , optarg );
@@ -261,12 +261,20 @@ cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz)
261
261
SOL_SOCKET , SO_MARK , & opt .mark );
262
262
ca_write_cmsg_u32 (cbuf , cbuf_sz , & cmsg_len ,
263
263
SOL_SOCKET , SO_PRIORITY , & opt .priority );
264
- ca_write_cmsg_u32 (cbuf , cbuf_sz , & cmsg_len ,
265
- SOL_IPV6 , IPV6_DONTFRAG , & opt .v6 .dontfrag );
266
- ca_write_cmsg_u32 (cbuf , cbuf_sz , & cmsg_len ,
267
- SOL_IPV6 , IPV6_TCLASS , & opt .v6 .tclass );
268
- ca_write_cmsg_u32 (cbuf , cbuf_sz , & cmsg_len ,
269
- SOL_IPV6 , IPV6_HOPLIMIT , & opt .v6 .hlimit );
264
+
265
+ if (opt .sock .family == AF_INET ) {
266
+ ca_write_cmsg_u32 (cbuf , cbuf_sz , & cmsg_len ,
267
+ SOL_IP , IP_TOS , & opt .cmsg .tclass );
268
+ ca_write_cmsg_u32 (cbuf , cbuf_sz , & cmsg_len ,
269
+ SOL_IP , IP_TTL , & opt .cmsg .hlimit );
270
+ } else {
271
+ ca_write_cmsg_u32 (cbuf , cbuf_sz , & cmsg_len ,
272
+ SOL_IPV6 , IPV6_DONTFRAG , & opt .cmsg .dontfrag );
273
+ ca_write_cmsg_u32 (cbuf , cbuf_sz , & cmsg_len ,
274
+ SOL_IPV6 , IPV6_TCLASS , & opt .cmsg .tclass );
275
+ ca_write_cmsg_u32 (cbuf , cbuf_sz , & cmsg_len ,
276
+ SOL_IPV6 , IPV6_HOPLIMIT , & opt .cmsg .hlimit );
277
+ }
270
278
271
279
if (opt .txtime .ena ) {
272
280
__u64 txtime ;
@@ -297,14 +305,14 @@ cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz)
297
305
* (__u32 * )CMSG_DATA (cmsg ) = SOF_TIMESTAMPING_TX_SCHED |
298
306
SOF_TIMESTAMPING_TX_SOFTWARE ;
299
307
}
300
- if (opt .v6 .exthdr .ena ) {
308
+ if (opt .cmsg .exthdr .ena ) {
301
309
cmsg = (struct cmsghdr * )(cbuf + cmsg_len );
302
310
cmsg_len += CMSG_SPACE (8 );
303
311
if (cbuf_sz < cmsg_len )
304
312
error (ERN_CMSG_WR , EFAULT , "cmsg buffer too small" );
305
313
306
314
cmsg -> cmsg_level = SOL_IPV6 ;
307
- cmsg -> cmsg_type = opt .v6 .exthdr .val ;
315
+ cmsg -> cmsg_type = opt .cmsg .exthdr .val ;
308
316
cmsg -> cmsg_len = CMSG_LEN (8 );
309
317
* (__u64 * )CMSG_DATA (cmsg ) = 0 ;
310
318
}
@@ -405,23 +413,35 @@ static void ca_set_sockopts(int fd)
405
413
setsockopt (fd , SOL_SOCKET , SO_MARK ,
406
414
& opt .sockopt .mark , sizeof (opt .sockopt .mark )))
407
415
error (ERN_SOCKOPT , errno , "setsockopt SO_MARK" );
408
- if (opt .sockopt .dontfrag &&
409
- setsockopt (fd , SOL_IPV6 , IPV6_DONTFRAG ,
410
- & opt .sockopt .dontfrag , sizeof (opt .sockopt .dontfrag )))
411
- error (ERN_SOCKOPT , errno , "setsockopt IPV6_DONTFRAG" );
412
- if (opt .sockopt .tclass &&
413
- setsockopt (fd , SOL_IPV6 , IPV6_TCLASS ,
414
- & opt .sockopt .tclass , sizeof (opt .sockopt .tclass )))
415
- error (ERN_SOCKOPT , errno , "setsockopt IPV6_TCLASS" );
416
- if (opt .sockopt .hlimit &&
417
- setsockopt (fd , SOL_IPV6 , IPV6_UNICAST_HOPS ,
418
- & opt .sockopt .hlimit , sizeof (opt .sockopt .hlimit )))
419
- error (ERN_SOCKOPT , errno , "setsockopt IPV6_HOPLIMIT" );
420
416
if (opt .sockopt .priority &&
421
417
setsockopt (fd , SOL_SOCKET , SO_PRIORITY ,
422
418
& opt .sockopt .priority , sizeof (opt .sockopt .priority )))
423
419
error (ERN_SOCKOPT , errno , "setsockopt SO_PRIORITY" );
424
420
421
+ if (opt .sock .family == AF_INET ) {
422
+ if (opt .sockopt .tclass &&
423
+ setsockopt (fd , SOL_IP , IP_TOS ,
424
+ & opt .sockopt .tclass , sizeof (opt .sockopt .tclass )))
425
+ error (ERN_SOCKOPT , errno , "setsockopt IP_TOS" );
426
+ if (opt .sockopt .hlimit &&
427
+ setsockopt (fd , SOL_IP , IP_TTL ,
428
+ & opt .sockopt .hlimit , sizeof (opt .sockopt .hlimit )))
429
+ error (ERN_SOCKOPT , errno , "setsockopt IP_TTL" );
430
+ } else {
431
+ if (opt .sockopt .dontfrag &&
432
+ setsockopt (fd , SOL_IPV6 , IPV6_DONTFRAG ,
433
+ & opt .sockopt .dontfrag , sizeof (opt .sockopt .dontfrag )))
434
+ error (ERN_SOCKOPT , errno , "setsockopt IPV6_DONTFRAG" );
435
+ if (opt .sockopt .tclass &&
436
+ setsockopt (fd , SOL_IPV6 , IPV6_TCLASS ,
437
+ & opt .sockopt .tclass , sizeof (opt .sockopt .tclass )))
438
+ error (ERN_SOCKOPT , errno , "setsockopt IPV6_TCLASS" );
439
+ if (opt .sockopt .hlimit &&
440
+ setsockopt (fd , SOL_IPV6 , IPV6_UNICAST_HOPS ,
441
+ & opt .sockopt .hlimit , sizeof (opt .sockopt .hlimit )))
442
+ error (ERN_SOCKOPT , errno , "setsockopt IPV6_HOPLIMIT" );
443
+ }
444
+
425
445
if (opt .txtime .ena ) {
426
446
struct sock_txtime so_txtime = {
427
447
.clockid = CLOCK_MONOTONIC ,
0 commit comments