123 #include <netlink-private/netlink.h>
124 #include <netlink/netlink.h>
125 #include <netlink/cache.h>
126 #include <netlink/object.h>
127 #include <netlink/xfrm/ae.h>
128 #include <linux/xfrm.h>
131 #define XFRM_AE_ATTR_DADDR 0x01
132 #define XFRM_AE_ATTR_SPI 0x02
133 #define XFRM_AE_ATTR_PROTO 0x04
134 #define XFRM_AE_ATTR_SADDR 0x08
135 #define XFRM_AE_ATTR_FLAGS 0x10
136 #define XFRM_AE_ATTR_REQID 0x20
137 #define XFRM_AE_ATTR_MARK 0x40
138 #define XFRM_AE_ATTR_LIFETIME 0x80
139 #define XFRM_AE_ATTR_REPLAY_MAXAGE 0x100
140 #define XFRM_AE_ATTR_REPLAY_MAXDIFF 0x200
141 #define XFRM_AE_ATTR_REPLAY_STATE 0x400
142 #define XFRM_AE_ATTR_FAMILY 0x800
144 static struct nl_object_ops xfrm_ae_obj_ops;
148 static void xfrm_ae_free_data(
struct nl_object *c)
150 struct xfrmnl_ae* ae = nl_object_priv (c);
158 if (ae->replay_state_esn)
159 free (ae->replay_state_esn);
162 static int xfrm_ae_clone(
struct nl_object *_dst,
struct nl_object *_src)
164 struct xfrmnl_ae* dst = nl_object_priv(_dst);
165 struct xfrmnl_ae* src = nl_object_priv(_src);
167 dst->sa_id.daddr = NULL;
169 dst->replay_state_esn = NULL;
171 if (src->sa_id.daddr) {
172 if ((dst->sa_id.daddr =
nl_addr_clone (src->sa_id.daddr)) == NULL)
181 if (src->replay_state_esn) {
182 uint32_t len =
sizeof (
struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * src->replay_state_esn->bmp_len);
184 if ((dst->replay_state_esn = malloc (len)) == NULL)
186 memcpy (dst->replay_state_esn, src->replay_state_esn, len);
192 static uint64_t xfrm_ae_compare(
struct nl_object *_a,
struct nl_object *_b,
193 uint64_t attrs,
int flags)
195 struct xfrmnl_ae* a = (
struct xfrmnl_ae *) _a;
196 struct xfrmnl_ae* b = (
struct xfrmnl_ae *) _b;
200 #define XFRM_AE_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, XFRM_AE_ATTR_##ATTR, a, b, EXPR)
201 diff |= XFRM_AE_DIFF(DADDR,
nl_addr_cmp(a->sa_id.daddr, b->sa_id.daddr));
202 diff |= XFRM_AE_DIFF(SPI, a->sa_id.spi != b->sa_id.spi);
203 diff |= XFRM_AE_DIFF(PROTO, a->sa_id.proto != b->sa_id.proto);
204 diff |= XFRM_AE_DIFF(SADDR,
nl_addr_cmp(a->saddr, b->saddr));
205 diff |= XFRM_AE_DIFF(FLAGS, a->flags != b->flags);
206 diff |= XFRM_AE_DIFF(REQID, a->reqid != b->reqid);
207 diff |= XFRM_AE_DIFF(MARK, (a->mark.v & a->mark.m) != (b->mark.v & b->mark.m));
208 diff |= XFRM_AE_DIFF(REPLAY_MAXAGE, a->replay_maxage != b->replay_maxage);
209 diff |= XFRM_AE_DIFF(REPLAY_MAXDIFF, a->replay_maxdiff != b->replay_maxdiff);
212 found = AVAILABLE_MISMATCH (a, b, XFRM_AE_ATTR_REPLAY_STATE);
215 if (((a->replay_state_esn != NULL) && (b->replay_state_esn == NULL)) ||
216 ((a->replay_state_esn == NULL) && (b->replay_state_esn != NULL)))
221 if (a->replay_state_esn)
223 if (a->replay_state_esn->bmp_len != b->replay_state_esn->bmp_len)
227 uint32_t len =
sizeof (
struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * a->replay_state_esn->bmp_len);
228 diff |= memcmp (a->replay_state_esn, b->replay_state_esn, len);
233 if ((a->replay_state.oseq != b->replay_state.oseq) ||
234 (a->replay_state.seq != b->replay_state.seq) ||
235 (a->replay_state.bitmap != b->replay_state.bitmap))
249 static const struct trans_tbl ae_attrs[] =
251 __ADD(XFRM_AE_ATTR_DADDR, daddr),
252 __ADD(XFRM_AE_ATTR_SPI, spi),
253 __ADD(XFRM_AE_ATTR_PROTO, protocol),
254 __ADD(XFRM_AE_ATTR_SADDR, saddr),
255 __ADD(XFRM_AE_ATTR_FLAGS, flags),
256 __ADD(XFRM_AE_ATTR_REQID, reqid),
257 __ADD(XFRM_AE_ATTR_MARK, mark),
258 __ADD(XFRM_AE_ATTR_LIFETIME, cur_lifetime),
259 __ADD(XFRM_AE_ATTR_REPLAY_MAXAGE, replay_maxage),
260 __ADD(XFRM_AE_ATTR_REPLAY_MAXDIFF, replay_maxdiff),
261 __ADD(XFRM_AE_ATTR_REPLAY_STATE, replay_state),
264 static char* xfrm_ae_attrs2str (
int attrs,
char *buf,
size_t len)
266 return __flags2str(attrs, buf, len, ae_attrs, ARRAY_SIZE(ae_attrs));
275 static const struct trans_tbl ae_flags[] = {
276 __ADD(XFRM_AE_UNSPEC, unspecified),
277 __ADD(XFRM_AE_RTHR, replay threshold),
278 __ADD(XFRM_AE_RVAL, replay value),
279 __ADD(XFRM_AE_LVAL, lifetime value),
280 __ADD(XFRM_AE_ETHR, expiry time threshold),
281 __ADD(XFRM_AE_CR, replay update event),
282 __ADD(XFRM_AE_CE, timer expiry event),
283 __ADD(XFRM_AE_CU, policy update event),
286 char* xfrmnl_ae_flags2str(
int flags,
char *buf,
size_t len)
288 return __flags2str (flags, buf, len, ae_flags, ARRAY_SIZE(ae_flags));
291 int xfrmnl_ae_str2flag(
const char *name)
293 return __str2flags(name, ae_flags, ARRAY_SIZE(ae_flags));
297 static void xfrm_ae_dump_line(
struct nl_object *a,
struct nl_dump_params *p)
299 char dst[INET6_ADDRSTRLEN+5], src[INET6_ADDRSTRLEN+5];
300 struct xfrmnl_ae* ae = (
struct xfrmnl_ae *) a;
301 char flags[128], buf[128];
302 time_t add_time, use_time;
303 struct tm *add_time_tm, *use_time_tm;
305 nl_dump_line(p,
"src %s dst %s \n",
nl_addr2str(ae->saddr, src,
sizeof(src)),
308 nl_dump_line(p,
"\tproto %s spi 0x%x reqid %u ",
309 nl_ip_proto2str (ae->sa_id.proto, buf, sizeof (buf)),
310 ae->sa_id.spi, ae->reqid);
312 xfrmnl_ae_flags2str(ae->flags, flags, sizeof (flags));
313 nl_dump_line(p,
"flags %s(0x%x) mark mask/value 0x%x/0x%x \n", flags,
314 ae->flags, ae->mark.m, ae->mark.v);
316 nl_dump_line(p,
"\tlifetime current: \n");
317 nl_dump_line(p,
"\t\tbytes %llu packets %llu \n", ae->lifetime_cur.bytes,
318 ae->lifetime_cur.packets);
319 if (ae->lifetime_cur.add_time != 0)
321 add_time = ae->lifetime_cur.add_time;
322 add_time_tm = gmtime (&add_time);
323 strftime (flags, 128,
"%Y-%m-%d %H-%M-%S", add_time_tm);
327 sprintf (flags,
"%s",
"-");
330 if (ae->lifetime_cur.use_time != 0)
332 use_time = ae->lifetime_cur.use_time;
333 use_time_tm = gmtime (&use_time);
334 strftime (buf, 128,
"%Y-%m-%d %H-%M-%S", use_time_tm);
338 sprintf (buf,
"%s",
"-");
340 nl_dump_line(p,
"\t\tadd_time: %s, use_time: %s\n", flags, buf);
342 nl_dump_line(p,
"\treplay info: \n");
343 nl_dump_line(p,
"\t\tmax age %u max diff %u \n", ae->replay_maxage, ae->replay_maxdiff);
345 nl_dump_line(p,
"\treplay state info: \n");
346 if (ae->replay_state_esn)
348 nl_dump_line(p,
"\t\toseq %u seq %u oseq_hi %u seq_hi %u replay window: %u \n",
349 ae->replay_state_esn->oseq, ae->replay_state_esn->seq,
350 ae->replay_state_esn->oseq_hi, ae->replay_state_esn->seq_hi,
351 ae->replay_state_esn->replay_window);
355 nl_dump_line(p,
"\t\toseq %u seq %u bitmap: %u \n", ae->replay_state.oseq,
356 ae->replay_state.seq, ae->replay_state.bitmap);
362 static void xfrm_ae_dump_details(
struct nl_object *a,
struct nl_dump_params *p)
364 xfrm_ae_dump_line(a, p);
367 static void xfrm_ae_dump_stats(
struct nl_object *a,
struct nl_dump_params *p)
369 xfrm_ae_dump_details(a, p);
373 static int build_xfrm_ae_message(
struct xfrmnl_ae *tmpl,
int cmd,
int flags,
374 struct nl_msg **result)
377 struct xfrm_aevent_id ae_id;
379 if (!(tmpl->ce_mask & XFRM_AE_ATTR_DADDR) ||
380 !(tmpl->ce_mask & XFRM_AE_ATTR_SPI) ||
381 !(tmpl->ce_mask & XFRM_AE_ATTR_PROTO))
382 return -NLE_MISSING_ATTR;
385 ae_id.sa_id.spi = htonl(tmpl->sa_id.spi);
386 ae_id.sa_id.family = tmpl->sa_id.family;
387 ae_id.sa_id.proto = tmpl->sa_id.proto;
389 if (tmpl->ce_mask & XFRM_AE_ATTR_SADDR)
392 if (tmpl->ce_mask & XFRM_AE_ATTR_FLAGS)
393 ae_id.flags = tmpl->flags;
395 if (tmpl->ce_mask & XFRM_AE_ATTR_REQID)
396 ae_id.reqid = tmpl->reqid;
402 if (
nlmsg_append(msg, &ae_id,
sizeof(ae_id), NLMSG_ALIGNTO) < 0)
403 goto nla_put_failure;
405 if (tmpl->ce_mask & XFRM_AE_ATTR_MARK)
406 NLA_PUT (msg, XFRMA_MARK,
sizeof (
struct xfrmnl_mark), &tmpl->mark);
408 if (tmpl->ce_mask & XFRM_AE_ATTR_LIFETIME)
409 NLA_PUT (msg, XFRMA_LTIME_VAL,
sizeof (
struct xfrmnl_lifetime_cur), &tmpl->lifetime_cur);
411 if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_MAXAGE)
412 NLA_PUT_U32 (msg, XFRMA_ETIMER_THRESH, tmpl->replay_maxage);
414 if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_MAXDIFF)
415 NLA_PUT_U32 (msg, XFRMA_REPLAY_THRESH, tmpl->replay_maxdiff);
417 if (tmpl->ce_mask & XFRM_AE_ATTR_REPLAY_STATE) {
418 if (tmpl->replay_state_esn) {
419 uint32_t len =
sizeof (
struct xfrm_replay_state_esn) + (sizeof (uint32_t) * tmpl->replay_state_esn->bmp_len);
420 NLA_PUT (msg, XFRMA_REPLAY_ESN_VAL, len, tmpl->replay_state_esn);
423 NLA_PUT (msg, XFRMA_REPLAY_VAL,
sizeof (
struct xfrmnl_replay_state), &tmpl->replay_state);
440 int xfrmnl_ae_set(
struct nl_sock* sk,
struct xfrmnl_ae* ae,
int flags)
445 if ((err = build_xfrm_ae_message(ae, XFRM_MSG_NEWAE, flags|NLM_F_REPLACE, &msg)) < 0)
463 struct xfrmnl_ae* xfrmnl_ae_alloc(
void)
468 void xfrmnl_ae_put(
struct xfrmnl_ae* ae)
475 static struct nla_policy xfrm_ae_policy[XFRMA_MAX+1] = {
476 [XFRMA_LTIME_VAL] = { .
minlen =
sizeof(
struct xfrm_lifetime_cur) },
477 [XFRMA_REPLAY_VAL] = { .minlen =
sizeof(
struct xfrm_replay_state) },
478 [XFRMA_REPLAY_THRESH] = { .type =
NLA_U32 },
479 [XFRMA_ETIMER_THRESH] = { .type =
NLA_U32 },
480 [XFRMA_SRCADDR] = { .minlen =
sizeof(xfrm_address_t) },
481 [XFRMA_MARK] = { .minlen =
sizeof(
struct xfrm_mark) },
482 [XFRMA_REPLAY_ESN_VAL] = { .minlen =
sizeof(
struct xfrm_replay_state_esn) },
485 int xfrmnl_ae_parse(
struct nlmsghdr *n,
struct xfrmnl_ae **result)
487 struct xfrmnl_ae* ae;
488 struct nlattr *tb[XFRMA_MAX + 1];
489 struct xfrm_aevent_id* ae_id;
492 ae = xfrmnl_ae_alloc();
498 ae->ce_msgtype = n->nlmsg_type;
501 err =
nlmsg_parse(n,
sizeof(
struct xfrm_aevent_id), tb, XFRMA_MAX, xfrm_ae_policy);
505 ae->sa_id.daddr =
nl_addr_build(ae_id->sa_id.family, &ae_id->sa_id.daddr, sizeof (ae_id->sa_id.daddr));
506 ae->sa_id.family= ae_id->sa_id.family;
507 ae->sa_id.spi = ntohl(ae_id->sa_id.spi);
508 ae->sa_id.proto = ae_id->sa_id.proto;
509 ae->saddr =
nl_addr_build(ae_id->sa_id.family, &ae_id->saddr, sizeof (ae_id->saddr));
510 ae->reqid = ae_id->reqid;
511 ae->flags = ae_id->flags;
512 ae->ce_mask |= (XFRM_AE_ATTR_DADDR | XFRM_AE_ATTR_FAMILY | XFRM_AE_ATTR_SPI |
513 XFRM_AE_ATTR_PROTO | XFRM_AE_ATTR_SADDR | XFRM_AE_ATTR_REQID |
516 if (tb[XFRMA_MARK]) {
517 struct xfrm_mark* m =
nla_data(tb[XFRMA_MARK]);
520 ae->ce_mask |= XFRM_AE_ATTR_MARK;
523 if (tb[XFRMA_LTIME_VAL]) {
524 struct xfrm_lifetime_cur* cur =
nla_data(tb[XFRMA_LTIME_VAL]);
525 ae->lifetime_cur.bytes = cur->bytes;
526 ae->lifetime_cur.packets = cur->packets;
527 ae->lifetime_cur.add_time = cur->add_time;
528 ae->lifetime_cur.use_time = cur->use_time;
529 ae->ce_mask |= XFRM_AE_ATTR_LIFETIME;
532 if (tb[XFRM_AE_ETHR]) {
533 ae->replay_maxage = *(uint32_t*)
nla_data(tb[XFRM_AE_ETHR]);
534 ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXAGE;
537 if (tb[XFRM_AE_RTHR]) {
538 ae->replay_maxdiff = *(uint32_t*)
nla_data(tb[XFRM_AE_RTHR]);
539 ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXDIFF;
542 if (tb[XFRMA_REPLAY_ESN_VAL]) {
543 struct xfrm_replay_state_esn* esn =
nla_data (tb[XFRMA_REPLAY_ESN_VAL]);
544 uint32_t len =
sizeof (
struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * esn->bmp_len);
546 if ((ae->replay_state_esn = calloc (1, len)) == NULL) {
550 ae->replay_state_esn->oseq = esn->oseq;
551 ae->replay_state_esn->seq = esn->seq;
552 ae->replay_state_esn->oseq_hi = esn->oseq_hi;
553 ae->replay_state_esn->seq_hi = esn->seq_hi;
554 ae->replay_state_esn->replay_window = esn->replay_window;
555 ae->replay_state_esn->bmp_len = esn->bmp_len;
556 memcpy (ae->replay_state_esn->bmp, esn->bmp, sizeof (uint32_t) * esn->bmp_len);
557 ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE;
561 struct xfrm_replay_state* replay_state =
nla_data (tb[XFRMA_REPLAY_VAL]);
562 ae->replay_state.oseq = replay_state->oseq;
563 ae->replay_state.seq = replay_state->seq;
564 ae->replay_state.bitmap = replay_state->bitmap;
565 ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE;
567 ae->replay_state_esn = NULL;
578 static int xfrm_ae_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
579 struct nlmsghdr *n,
struct nl_parser_param *pp)
581 struct xfrmnl_ae* ae;
584 if ((err = xfrmnl_ae_parse(n, &ae)) < 0)
587 err = pp->pp_cb((
struct nl_object *) ae, pp);
598 int xfrmnl_ae_build_get_request(
struct nl_addr* daddr,
unsigned int spi,
unsigned int protocol,
599 unsigned int mark_mask,
unsigned int mark_value,
struct nl_msg **result)
602 struct xfrm_aevent_id ae_id;
603 struct xfrmnl_mark mark;
607 fprintf(stderr,
"APPLICATION BUG: %s:%d:%s: A valid destination address, spi must be specified\n",
608 __FILE__, __LINE__, __func__);
610 return -NLE_MISSING_ATTR;
613 memset(&ae_id, 0,
sizeof(ae_id));
615 ae_id.sa_id.spi = htonl(spi);
617 ae_id.sa_id.proto = protocol;
622 if (
nlmsg_append(msg, &ae_id,
sizeof(ae_id), NLMSG_ALIGNTO) < 0)
623 goto nla_put_failure;
627 NLA_PUT (msg, XFRMA_MARK,
sizeof (
struct xfrmnl_mark), &mark);
637 int xfrmnl_ae_get_kernel(
struct nl_sock* sock,
struct nl_addr* daddr,
unsigned int spi,
unsigned int protocol,
638 unsigned int mark_mask,
unsigned int mark_value,
struct xfrmnl_ae** result)
640 struct nl_msg *msg = NULL;
641 struct nl_object *obj;
644 if ((err = xfrmnl_ae_build_get_request(daddr, spi, protocol, mark_mask, mark_value, &msg)) < 0)
652 if ((err =
nl_pickup(sock, &xfrm_ae_msg_parser, &obj)) < 0)
656 *result = (
struct xfrmnl_ae *) obj;
672 static inline int __assign_addr(
struct xfrmnl_ae* ae,
struct nl_addr **pos,
673 struct nl_addr *
new,
int flag,
int nocheck)
676 if (ae->ce_mask & XFRM_AE_ATTR_FAMILY) {
678 return -NLE_AF_MISMATCH;
681 ae->ce_mask |= XFRM_AE_ATTR_FAMILY;
697 struct nl_addr* xfrmnl_ae_get_daddr (
struct xfrmnl_ae* ae)
699 if (ae->ce_mask & XFRM_AE_ATTR_DADDR)
700 return ae->sa_id.daddr;
705 int xfrmnl_ae_set_daddr (
struct xfrmnl_ae* ae,
struct nl_addr* addr)
707 return __assign_addr(ae, &ae->sa_id.daddr, addr, XFRM_AE_ATTR_DADDR, 0);
710 int xfrmnl_ae_get_spi (
struct xfrmnl_ae* ae)
712 if (ae->ce_mask & XFRM_AE_ATTR_SPI)
713 return ae->sa_id.spi;
718 int xfrmnl_ae_set_spi (
struct xfrmnl_ae* ae,
unsigned int spi)
721 ae->ce_mask |= XFRM_AE_ATTR_SPI;
726 int xfrmnl_ae_get_family (
struct xfrmnl_ae* ae)
728 if (ae->ce_mask & XFRM_AE_ATTR_FAMILY)
729 return ae->sa_id.family;
734 int xfrmnl_ae_set_family (
struct xfrmnl_ae* ae,
unsigned int family)
736 ae->sa_id.family = family;
737 ae->ce_mask |= XFRM_AE_ATTR_FAMILY;
742 int xfrmnl_ae_get_proto (
struct xfrmnl_ae* ae)
744 if (ae->ce_mask & XFRM_AE_ATTR_PROTO)
745 return ae->sa_id.proto;
750 int xfrmnl_ae_set_proto (
struct xfrmnl_ae* ae,
unsigned int protocol)
752 ae->sa_id.proto = protocol;
753 ae->ce_mask |= XFRM_AE_ATTR_PROTO;
758 struct nl_addr* xfrmnl_ae_get_saddr (
struct xfrmnl_ae* ae)
760 if (ae->ce_mask & XFRM_AE_ATTR_SADDR)
766 int xfrmnl_ae_set_saddr (
struct xfrmnl_ae* ae,
struct nl_addr* addr)
768 return __assign_addr(ae, &ae->saddr, addr, XFRM_AE_ATTR_SADDR, 1);
771 int xfrmnl_ae_get_flags (
struct xfrmnl_ae* ae)
773 if (ae->ce_mask & XFRM_AE_ATTR_FLAGS)
779 int xfrmnl_ae_set_flags (
struct xfrmnl_ae* ae,
unsigned int flags)
782 ae->ce_mask |= XFRM_AE_ATTR_FLAGS;
787 int xfrmnl_ae_get_reqid (
struct xfrmnl_ae* ae)
789 if (ae->ce_mask & XFRM_AE_ATTR_REQID)
795 int xfrmnl_ae_set_reqid (
struct xfrmnl_ae* ae,
unsigned int reqid)
798 ae->ce_mask |= XFRM_AE_ATTR_REQID;
803 int xfrmnl_ae_get_mark (
struct xfrmnl_ae* ae,
unsigned int* mark_mask,
unsigned int* mark_value)
805 if (mark_mask == NULL || mark_value == NULL)
808 if (ae->ce_mask & XFRM_AE_ATTR_MARK)
810 *mark_mask = ae->mark.m;
811 *mark_value = ae->mark.v;
819 int xfrmnl_ae_set_mark (
struct xfrmnl_ae* ae,
unsigned int value,
unsigned int mask)
823 ae->ce_mask |= XFRM_AE_ATTR_MARK;
828 int xfrmnl_ae_get_curlifetime (
struct xfrmnl_ae* ae,
unsigned long long int* curr_bytes,
829 unsigned long long int* curr_packets,
unsigned long long int* curr_add_time,
830 unsigned long long int* curr_use_time)
832 if (curr_bytes == NULL || curr_packets == NULL || curr_add_time == NULL || curr_use_time == NULL)
835 if (ae->ce_mask & XFRM_AE_ATTR_LIFETIME)
837 *curr_bytes = ae->lifetime_cur.bytes;
838 *curr_packets = ae->lifetime_cur.packets;
839 *curr_add_time = ae->lifetime_cur.add_time;
840 *curr_use_time = ae->lifetime_cur.use_time;
848 int xfrmnl_ae_set_curlifetime (
struct xfrmnl_ae* ae,
unsigned long long int curr_bytes,
849 unsigned long long int curr_packets,
unsigned long long int curr_add_time,
850 unsigned long long int curr_use_time)
852 ae->lifetime_cur.bytes = curr_bytes;
853 ae->lifetime_cur.packets = curr_packets;
854 ae->lifetime_cur.add_time = curr_add_time;
855 ae->lifetime_cur.use_time = curr_use_time;
856 ae->ce_mask |= XFRM_AE_ATTR_LIFETIME;
861 int xfrmnl_ae_get_replay_maxage (
struct xfrmnl_ae* ae)
863 if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_MAXAGE)
864 return ae->replay_maxage;
869 int xfrmnl_ae_set_replay_maxage (
struct xfrmnl_ae* ae,
unsigned int replay_maxage)
871 ae->replay_maxage = replay_maxage;
872 ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXAGE;
877 int xfrmnl_ae_get_replay_maxdiff (
struct xfrmnl_ae* ae)
879 if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_MAXDIFF)
880 return ae->replay_maxdiff;
885 int xfrmnl_ae_set_replay_maxdiff (
struct xfrmnl_ae* ae,
unsigned int replay_maxdiff)
887 ae->replay_maxdiff = replay_maxdiff;
888 ae->ce_mask |= XFRM_AE_ATTR_REPLAY_MAXDIFF;
893 int xfrmnl_ae_get_replay_state (
struct xfrmnl_ae* ae,
unsigned int* oseq,
unsigned int* seq,
unsigned int* bmp)
895 if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_STATE)
897 if (ae->replay_state_esn == NULL)
899 *oseq = ae->replay_state.oseq;
900 *seq = ae->replay_state.seq;
901 *bmp = ae->replay_state.bitmap;
914 int xfrmnl_ae_set_replay_state (
struct xfrmnl_ae* ae,
unsigned int oseq,
unsigned int seq,
unsigned int bitmap)
916 ae->replay_state.oseq = oseq;
917 ae->replay_state.seq = seq;
918 ae->replay_state.bitmap = bitmap;
919 ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE;
924 int xfrmnl_ae_get_replay_state_esn(
struct xfrmnl_ae* ae,
unsigned int* oseq,
unsigned int* seq,
unsigned int* oseq_hi,
925 unsigned int* seq_hi,
unsigned int* replay_window,
unsigned int* bmp_len,
unsigned int* bmp)
927 if (ae->ce_mask & XFRM_AE_ATTR_REPLAY_STATE)
929 if (ae->replay_state_esn)
931 *oseq = ae->replay_state_esn->oseq;
932 *seq = ae->replay_state_esn->seq;
933 *oseq_hi= ae->replay_state_esn->oseq_hi;
934 *seq_hi = ae->replay_state_esn->seq_hi;
935 *replay_window = ae->replay_state_esn->replay_window;
936 *bmp_len = ae->replay_state_esn->bmp_len;
937 memcpy (bmp, ae->replay_state_esn->bmp, ae->replay_state_esn->bmp_len * sizeof (uint32_t));
950 int xfrmnl_ae_set_replay_state_esn(
struct xfrmnl_ae* ae,
unsigned int oseq,
unsigned int seq,
951 unsigned int oseq_hi,
unsigned int seq_hi,
unsigned int replay_window,
952 unsigned int bmp_len,
unsigned int* bmp)
955 if (ae->replay_state_esn)
956 free (ae->replay_state_esn);
958 if ((ae->replay_state_esn = calloc (1,
sizeof (
struct xfrmnl_replay_state_esn) +
sizeof (uint32_t) * bmp_len)) == NULL)
961 ae->replay_state_esn->oseq = oseq;
962 ae->replay_state_esn->seq = seq;
963 ae->replay_state_esn->oseq_hi = oseq_hi;
964 ae->replay_state_esn->seq_hi = seq_hi;
965 ae->replay_state_esn->replay_window = replay_window;
966 ae->replay_state_esn->bmp_len = bmp_len;
967 memcpy (ae->replay_state_esn->bmp, bmp, bmp_len * sizeof (uint32_t));
968 ae->ce_mask |= XFRM_AE_ATTR_REPLAY_STATE;
975 static struct nl_object_ops xfrm_ae_obj_ops = {
976 .oo_name =
"xfrm/ae",
977 .oo_size =
sizeof(
struct xfrmnl_ae),
978 .oo_free_data = xfrm_ae_free_data,
979 .oo_clone = xfrm_ae_clone,
985 .oo_compare = xfrm_ae_compare,
986 .oo_attrs2str = xfrm_ae_attrs2str,
987 .oo_id_attrs = (XFRM_AE_ATTR_DADDR | XFRM_AE_ATTR_SPI | XFRM_AE_ATTR_PROTO),
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
struct nl_addr * nl_addr_build(int family, const void *buf, size_t size)
Allocate abstract address based on a binary address.
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy)
parse attributes of a netlink message
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message.
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
int nl_pickup(struct nl_sock *sk, int(*parser)(struct nl_cache_ops *, struct sockaddr_nl *, struct nlmsghdr *, struct nl_parser_param *), struct nl_object **result)
Pickup netlink answer, parse is and return object.
int nl_wait_for_ack(struct nl_sock *sk)
Wait for ACK.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
@ NL_DUMP_STATS
Dump all attributes including statistics.
@ NL_DUMP_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Attribute validation policy.
uint16_t minlen
Minimal length of payload required.