#ifndef _NET_OVPN_OVPNPKTID_H_
#define _NET_OVPN_OVPNPKTID_H_
#include "proto.h"
#define PKTID_RECV_EXPIRE (30 * HZ)
struct ovpn_pktid_xmit {
atomic_t seq_num;
};
#define REPLAY_WINDOW_ORDER 8
#define REPLAY_WINDOW_BYTES BIT(REPLAY_WINDOW_ORDER)
#define REPLAY_WINDOW_SIZE (REPLAY_WINDOW_BYTES * 8)
#define REPLAY_INDEX(base, i) (((base) + (i)) & (REPLAY_WINDOW_SIZE - 1))
struct ovpn_pktid_recv {
DECLARE_BITMAP(history, REPLAY_WINDOW_SIZE);
unsigned int base;
unsigned int extent;
unsigned long expire;
u32 id;
u32 time;
u32 id_floor;
unsigned int max_backtrack;
spinlock_t lock;
};
static inline int ovpn_pktid_xmit_next(struct ovpn_pktid_xmit *pid, u32 *pktid)
{
const u32 seq_num = atomic_fetch_add_unless(&pid->seq_num, 1, 0);
if (unlikely(!seq_num))
return -ERANGE;
*pktid = seq_num;
return 0;
}
static inline void ovpn_pktid_aead_write(const u32 pktid,
const u8 nt[],
unsigned char *dest)
{
*(__force __be32 *)(dest) = htonl(pktid);
BUILD_BUG_ON(4 + OVPN_NONCE_TAIL_SIZE != OVPN_NONCE_SIZE);
memcpy(dest + 4, nt, OVPN_NONCE_TAIL_SIZE);
}
void ovpn_pktid_xmit_init(struct ovpn_pktid_xmit *pid);
void ovpn_pktid_recv_init(struct ovpn_pktid_recv *pr);
int ovpn_pktid_recv(struct ovpn_pktid_recv *pr, u32 pkt_id, u32 pkt_time);
#endif