~james-page/ubuntu/saucy/openvswitch/1.12-snapshot

« back to all changes in this revision

Viewing changes to lib/netlink.c

  • Committer: James Page
  • Date: 2013-08-21 10:16:57 UTC
  • mfrom: (1.1.20)
  • Revision ID: james.page@canonical.com-20130821101657-3o0z0qeiv5zkwlzi
New upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
 
2
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
3
3
 *
4
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
5
 * you may not use this file except in compliance with the License.
21
21
#include <sys/types.h>
22
22
#include <unistd.h>
23
23
#include "coverage.h"
 
24
#include "flow.h"
24
25
#include "netlink-protocol.h"
25
26
#include "ofpbuf.h"
26
27
#include "timeval.h"
295
296
    nl_msg_put_unspec(msg, type, &value, sizeof value);
296
297
}
297
298
 
 
299
/* Appends a Netlink attribute of the given 'type' and the given odp_port_t
 
300
 * 'value' to 'msg'. */
 
301
void
 
302
nl_msg_put_odp_port(struct ofpbuf *msg, uint16_t type, odp_port_t value)
 
303
{
 
304
    nl_msg_put_u32(msg, type, odp_to_u32(value));
 
305
}
 
306
 
 
307
 
298
308
/* Appends a Netlink attribute of the given 'type' and the given
299
309
 * null-terminated string 'value' to 'msg'. */
300
310
void
570
580
    return get_32aligned_be64(x);
571
581
}
572
582
 
 
583
/* Returns the 32-bit odp_port_t value in 'nla''s payload.
 
584
 *
 
585
 * Asserts that 'nla''s payload is at least 4 bytes long. */
 
586
odp_port_t
 
587
nl_attr_get_odp_port(const struct nlattr *nla)
 
588
{
 
589
    return u32_to_odp(nl_attr_get_u32(nla));
 
590
}
 
591
 
573
592
/* Returns the null-terminated string value in 'nla''s payload.
574
593
 *
575
594
 * Asserts that 'nla''s payload contains a null-terminated string. */
588
607
    ofpbuf_use_const(nested, nl_attr_get(nla), nl_attr_get_size(nla));
589
608
}
590
609
 
591
 
/* Default minimum and maximum payload sizes for each type of attribute. */
592
 
static const size_t attr_len_range[][2] = {
593
 
    [0 ... N_NL_ATTR_TYPES - 1] = { 0, SIZE_MAX },
594
 
    [NL_A_U8] = { 1, 1 },
595
 
    [NL_A_U16] = { 2, 2 },
596
 
    [NL_A_U32] = { 4, 4 },
597
 
    [NL_A_U64] = { 8, 8 },
598
 
    [NL_A_STRING] = { 1, SIZE_MAX },
599
 
    [NL_A_FLAG] = { 0, SIZE_MAX },
600
 
    [NL_A_NESTED] = { 0, SIZE_MAX },
601
 
};
 
610
/* Default minimum payload size for each type of attribute. */
 
611
static size_t
 
612
min_attr_len(enum nl_attr_type type)
 
613
{
 
614
    switch (type) {
 
615
    case NL_A_NO_ATTR: return 0;
 
616
    case NL_A_UNSPEC: return 0;
 
617
    case NL_A_U8: return 1;
 
618
    case NL_A_U16: return 2;
 
619
    case NL_A_U32: return 4;
 
620
    case NL_A_U64: return 8;
 
621
    case NL_A_STRING: return 1;
 
622
    case NL_A_FLAG: return 0;
 
623
    case NL_A_NESTED: return 0;
 
624
    case N_NL_ATTR_TYPES: default: NOT_REACHED();
 
625
    }
 
626
}
 
627
 
 
628
/* Default maximum payload size for each type of attribute. */
 
629
static size_t
 
630
max_attr_len(enum nl_attr_type type)
 
631
{
 
632
    switch (type) {
 
633
    case NL_A_NO_ATTR: return SIZE_MAX;
 
634
    case NL_A_UNSPEC: return SIZE_MAX;
 
635
    case NL_A_U8: return 1;
 
636
    case NL_A_U16: return 2;
 
637
    case NL_A_U32: return 4;
 
638
    case NL_A_U64: return 8;
 
639
    case NL_A_STRING: return SIZE_MAX;
 
640
    case NL_A_FLAG: return SIZE_MAX;
 
641
    case NL_A_NESTED: return SIZE_MAX;
 
642
    case N_NL_ATTR_TYPES: default: NOT_REACHED();
 
643
    }
 
644
}
602
645
 
603
646
bool
604
647
nl_attr_validate(const struct nlattr *nla, const struct nl_policy *policy)
615
658
    /* Figure out min and max length. */
616
659
    min_len = policy->min_len;
617
660
    if (!min_len) {
618
 
        min_len = attr_len_range[policy->type][0];
 
661
        min_len = min_attr_len(policy->type);
619
662
    }
620
663
    max_len = policy->max_len;
621
664
    if (!max_len) {
622
 
        max_len = attr_len_range[policy->type][1];
 
665
        max_len = max_attr_len(policy->type);
623
666
    }
624
667
 
625
668
    /* Verify length. */
668
711
        return false;
669
712
    }
670
713
 
671
 
    NL_ATTR_FOR_EACH (nla, left,
672
 
                      (struct nlattr *) ((char *) msg->data + nla_offset),
 
714
    NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, nla_offset, 0),
673
715
                      msg->size - nla_offset)
674
716
    {
675
717
        uint16_t type = nl_attr_type(nla);
734
776
const struct nlattr *
735
777
nl_attr_find(const struct ofpbuf *buf, size_t hdr_len, uint16_t type)
736
778
{
737
 
    const uint8_t *start = (const uint8_t *) buf->data + hdr_len;
738
 
    return nl_attr_find__((const struct nlattr *) start, buf->size - hdr_len,
 
779
    return nl_attr_find__(ofpbuf_at(buf, hdr_len, 0), buf->size - hdr_len,
739
780
                          type);
740
781
}
741
782