Skip to content

Commit ef84703

Browse files
0x7f454c46davem330
authored andcommitted
net/tcp: Add TCP-AO getsockopt()s
Introduce getsockopt(TCP_AO_GET_KEYS) that lets a user get TCP-AO keys and their properties from a socket. The user can provide a filter to match the specific key to be dumped or ::get_all = 1 may be used to dump all keys in one syscall. Add another getsockopt(TCP_AO_INFO) for providing per-socket/per-ao_info stats: packet counters, Current_key/RNext_key and flags like ::ao_required and ::accept_icmps. Co-developed-by: Francesco Ruggeri <[email protected]> Signed-off-by: Francesco Ruggeri <[email protected]> Co-developed-by: Salam Noureddine <[email protected]> Signed-off-by: Salam Noureddine <[email protected]> Signed-off-by: Dmitry Safonov <[email protected]> Acked-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7753c2f commit ef84703

File tree

4 files changed

+369
-14
lines changed

4 files changed

+369
-14
lines changed

include/net/tcp_ao.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ int tcp_ao_calc_traffic_key(struct tcp_ao_key *mkt, u8 *key, void *ctx,
194194
void tcp_ao_destroy_sock(struct sock *sk, bool twsk);
195195
void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw, struct tcp_sock *tp);
196196
bool tcp_ao_ignore_icmp(const struct sock *sk, int family, int type, int code);
197+
int tcp_ao_get_mkts(struct sock *sk, sockptr_t optval, sockptr_t optlen);
198+
int tcp_ao_get_sock_info(struct sock *sk, sockptr_t optval, sockptr_t optlen);
197199
enum skb_drop_reason tcp_inbound_ao_hash(struct sock *sk,
198200
const struct sk_buff *skb, unsigned short int family,
199201
const struct request_sock *req,
@@ -316,6 +318,16 @@ static inline void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw,
316318
static inline void tcp_ao_connect_init(struct sock *sk)
317319
{
318320
}
321+
322+
static inline int tcp_ao_get_mkts(struct sock *sk, sockptr_t optval, sockptr_t optlen)
323+
{
324+
return -ENOPROTOOPT;
325+
}
326+
327+
static inline int tcp_ao_get_sock_info(struct sock *sk, sockptr_t optval, sockptr_t optlen)
328+
{
329+
return -ENOPROTOOPT;
330+
}
319331
#endif
320332

321333
#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)

include/uapi/linux/tcp.h

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ enum {
131131

132132
#define TCP_AO_ADD_KEY 38 /* Add/Set MKT */
133133
#define TCP_AO_DEL_KEY 39 /* Delete MKT */
134-
#define TCP_AO_INFO 40 /* Modify TCP-AO per-socket options */
134+
#define TCP_AO_INFO 40 /* Set/list TCP-AO per-socket options */
135+
#define TCP_AO_GET_KEYS 41 /* List MKT(s) */
135136

136137
#define TCP_REPAIR_ON 1
137138
#define TCP_REPAIR_OFF 0
@@ -405,21 +406,55 @@ struct tcp_ao_del { /* setsockopt(TCP_AO_DEL_KEY) */
405406
__u8 keyflags; /* see TCP_AO_KEYF_ */
406407
} __attribute__((aligned(8)));
407408

408-
struct tcp_ao_info_opt { /* setsockopt(TCP_AO_INFO) */
409-
__u32 set_current :1, /* corresponding ::current_key */
410-
set_rnext :1, /* corresponding ::rnext */
411-
ao_required :1, /* don't accept non-AO connects */
412-
set_counters :1, /* set/clear ::pkt_* counters */
413-
accept_icmps :1, /* accept incoming ICMPs */
409+
struct tcp_ao_info_opt { /* setsockopt(TCP_AO_INFO), getsockopt(TCP_AO_INFO) */
410+
/* Here 'in' is for setsockopt(), 'out' is for getsockopt() */
411+
__u32 set_current :1, /* in/out: corresponding ::current_key */
412+
set_rnext :1, /* in/out: corresponding ::rnext */
413+
ao_required :1, /* in/out: don't accept non-AO connects */
414+
set_counters :1, /* in: set/clear ::pkt_* counters */
415+
accept_icmps :1, /* in/out: accept incoming ICMPs */
414416
reserved :27; /* must be 0 */
415417
__u16 reserved2; /* padding, must be 0 */
416-
__u8 current_key; /* KeyID to set as Current_key */
417-
__u8 rnext; /* KeyID to set as Rnext_key */
418-
__u64 pkt_good; /* verified segments */
419-
__u64 pkt_bad; /* failed verification */
420-
__u64 pkt_key_not_found; /* could not find a key to verify */
421-
__u64 pkt_ao_required; /* segments missing TCP-AO sign */
422-
__u64 pkt_dropped_icmp; /* ICMPs that were ignored */
418+
__u8 current_key; /* in/out: KeyID of Current_key */
419+
__u8 rnext; /* in/out: keyid of RNext_key */
420+
__u64 pkt_good; /* in/out: verified segments */
421+
__u64 pkt_bad; /* in/out: failed verification */
422+
__u64 pkt_key_not_found; /* in/out: could not find a key to verify */
423+
__u64 pkt_ao_required; /* in/out: segments missing TCP-AO sign */
424+
__u64 pkt_dropped_icmp; /* in/out: ICMPs that were ignored */
425+
} __attribute__((aligned(8)));
426+
427+
struct tcp_ao_getsockopt { /* getsockopt(TCP_AO_GET_KEYS) */
428+
struct __kernel_sockaddr_storage addr; /* in/out: dump keys for peer
429+
* with this address/prefix
430+
*/
431+
char alg_name[64]; /* out: crypto hash algorithm */
432+
__u8 key[TCP_AO_MAXKEYLEN];
433+
__u32 nkeys; /* in: size of the userspace buffer
434+
* @optval, measured in @optlen - the
435+
* sizeof(struct tcp_ao_getsockopt)
436+
* out: number of keys that matched
437+
*/
438+
__u16 is_current :1, /* in: match and dump Current_key,
439+
* out: the dumped key is Current_key
440+
*/
441+
442+
is_rnext :1, /* in: match and dump RNext_key,
443+
* out: the dumped key is RNext_key
444+
*/
445+
get_all :1, /* in: dump all keys */
446+
reserved :13; /* padding, must be 0 */
447+
__u8 sndid; /* in/out: dump keys with SendID */
448+
__u8 rcvid; /* in/out: dump keys with RecvID */
449+
__u8 prefix; /* in/out: dump keys with address/prefix */
450+
__u8 maclen; /* out: key's length of authentication
451+
* code (hash)
452+
*/
453+
__u8 keyflags; /* in/out: see TCP_AO_KEYF_ */
454+
__u8 keylen; /* out: length of ::key */
455+
__s32 ifindex; /* in/out: L3 dev index for VRF */
456+
__u64 pkt_good; /* out: verified segments */
457+
__u64 pkt_bad; /* out: segments that failed verification */
423458
} __attribute__((aligned(8)));
424459

425460
/* setsockopt(fd, IPPROTO_TCP, TCP_ZEROCOPY_RECEIVE, ...) */

net/ipv4/tcp.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4284,6 +4284,19 @@ int do_tcp_getsockopt(struct sock *sk, int level,
42844284
return err;
42854285
}
42864286
#endif
4287+
case TCP_AO_GET_KEYS:
4288+
case TCP_AO_INFO: {
4289+
int err;
4290+
4291+
sockopt_lock_sock(sk);
4292+
if (optname == TCP_AO_GET_KEYS)
4293+
err = tcp_ao_get_mkts(sk, optval, optlen);
4294+
else
4295+
err = tcp_ao_get_sock_info(sk, optval, optlen);
4296+
sockopt_release_sock(sk);
4297+
4298+
return err;
4299+
}
42874300
default:
42884301
return -ENOPROTOOPT;
42894302
}

0 commit comments

Comments
 (0)