diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/agentx.c | 31 | ||||
| -rw-r--r-- | lib/if.c | 34 | ||||
| -rw-r--r-- | lib/if.h | 2 | ||||
| -rw-r--r-- | lib/smux.h | 45 | ||||
| -rw-r--r-- | lib/snmp.c | 54 | ||||
| -rw-r--r-- | lib/vrf.c | 50 | ||||
| -rw-r--r-- | lib/vrf.h | 15 |
7 files changed, 227 insertions, 4 deletions
diff --git a/lib/agentx.c b/lib/agentx.c index f049d699a8..dfe5d93754 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -271,6 +271,23 @@ int smux_trap(struct variable *vp, size_t vp_len, const oid *ename, const struct trap_object *trapobj, size_t trapobjlen, uint8_t sptrap) { + struct index_oid trap_index[1]; + + /* copy the single index into the multi-index format */ + oid_copy(trap_index[0].indexname, iname, inamelen); + trap_index[0].indexlen = inamelen; + + return (smux_trap_multi_index( + vp, vp_len, ename, enamelen, name, namelen, trap_index, + array_size(trap_index), trapobj, trapobjlen, sptrap)); +} + +int smux_trap_multi_index(struct variable *vp, size_t vp_len, const oid *ename, + size_t enamelen, const oid *name, size_t namelen, + struct index_oid *iname, size_t index_len, + const struct trap_object *trapobj, size_t trapobjlen, + uint8_t sptrap) +{ oid objid_snmptrap[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0}; size_t objid_snmptrap_len = sizeof(objid_snmptrap) / sizeof(oid); oid notification_oid[MAX_OID_LEN]; @@ -299,6 +316,13 @@ int smux_trap(struct variable *vp, size_t vp_len, const oid *ename, size_t val_len; WriteMethod *wm = NULL; struct variable cvp; + unsigned int iindex; + /* + * this allows the behaviour of smux_trap with a singe index + * for all objects to be maintained whilst allowing traps which + * have different indices per object to be supported + */ + iindex = (index_len == 1) ? 0 : i; /* Make OID. */ if (trapobj[i].namelen > 0) { @@ -306,8 +330,10 @@ int smux_trap(struct variable *vp, size_t vp_len, const oid *ename, onamelen = trapobj[i].namelen; oid_copy(oid, name, namelen); oid_copy(oid + namelen, trapobj[i].name, onamelen); - oid_copy(oid + namelen + onamelen, iname, inamelen); - oid_len = namelen + onamelen + inamelen; + oid_copy(oid + namelen + onamelen, + iname[iindex].indexname, + iname[iindex].indexlen); + oid_len = namelen + onamelen + iname[iindex].indexlen; } else { /* Scalar object */ onamelen = trapobj[i].namelen * (-1); @@ -333,6 +359,7 @@ int smux_trap(struct variable *vp, size_t vp_len, const oid *ename, cvp.magic = vp[j].magic; cvp.acl = vp[j].acl; cvp.findVar = vp[j].findVar; + /* Grab the result. */ val = cvp.findVar(&cvp, oid, &oid_len, 1, &val_len, &wm); @@ -351,6 +351,40 @@ struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id) return NULL; } +/* Interface existance check by index. */ +struct interface *if_vrf_lookup_by_index_next(ifindex_t ifindex, + vrf_id_t vrf_id) +{ + struct vrf *vrf = vrf_lookup_by_id(vrf_id); + struct interface *tmp_ifp; + bool found = false; + + if (!vrf) + return NULL; + + if (ifindex == 0) { + tmp_ifp = RB_MIN(if_index_head, &vrf->ifaces_by_index); + /* skip the vrf interface */ + if (tmp_ifp && if_is_vrf(tmp_ifp)) + ifindex = tmp_ifp->ifindex; + else + return tmp_ifp; + } + + RB_FOREACH (tmp_ifp, if_index_head, &vrf->ifaces_by_index) { + if (found) { + /* skip the vrf interface */ + if (tmp_ifp && if_is_vrf(tmp_ifp)) + continue; + else + return tmp_ifp; + } + if (tmp_ifp->ifindex == ifindex) + found = true; + } + return NULL; +} + const char *ifindex2ifname(ifindex_t ifindex, vrf_id_t vrf_id) { struct interface *ifp; @@ -513,6 +513,8 @@ extern struct interface *if_create_name(const char *name, vrf_id_t vrf_id); /* Create new interface, adds to index list only */ extern struct interface *if_create_ifindex(ifindex_t ifindex, vrf_id_t vrf_id); extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id); +extern struct interface *if_vrf_lookup_by_index_next(ifindex_t ifindex, + vrf_id_t vrf_id); extern struct interface *if_lookup_by_index_all_vrf(ifindex_t); extern struct interface *if_lookup_exact_address(const void *matchaddr, int family, vrf_id_t vrf_id); diff --git a/lib/smux.h b/lib/smux.h index 6896f02354..ff97c8ab51 100644 --- a/lib/smux.h +++ b/lib/smux.h @@ -44,6 +44,29 @@ extern "C" { #define IN_ADDR_SIZE sizeof(struct in_addr) +/* IANAipRouteProtocol */ +#define IANAIPROUTEPROTOCOLOTHER 1 +#define IANAIPROUTEPROTOCOLLOCAL 2 +#define IANAIPROUTEPROTOCOLNETMGMT 3 +#define IANAIPROUTEPROTOCOLICMP 4 +#define IANAIPROUTEPROTOCOLEGP 5 +#define IANAIPROUTEPROTOCOLGGP 6 +#define IANAIPROUTEPROTOCOLHELLO 7 +#define IANAIPROUTEPROTOCOLRIP 8 +#define IANAIPROUTEPROTOCOLISIS 9 +#define IANAIPROUTEPROTOCOLESIS 10 +#define IANAIPROUTEPROTOCOLCISCOIGRP 11 +#define IANAIPROUTEPROTOCOLBBNSPFIGP 12 +#define IANAIPROUTEPROTOCOLOSPF 13 +#define IANAIPROUTEPROTOCOLBGP 14 +#define IANAIPROUTEPROTOCOLIDPR 15 +#define IANAIPROUTEPROTOCOLCISCOEIGRP 16 +#define IANAIPROUTEPROTOCOLDVMRP 17 + +#define INETADDRESSTYPEUNKNOWN 0 +#define INETADDRESSTYPEIPV4 1 +#define INETADDRESSTYPEIPV6 2 + #undef REGISTER_MIB #define REGISTER_MIB(descr, var, vartype, theoid) \ smux_register_mib(descr, (struct variable *)var, \ @@ -56,19 +79,29 @@ struct trap_object { oid name[MAX_OID_LEN]; }; +struct index_oid { + int indexlen; + oid indexname[MAX_OID_LEN]; +}; /* Declare SMUX return value. */ #define SNMP_LOCAL_VARIABLES \ static long snmp_int_val __attribute__((unused)); \ static struct in_addr snmp_in_addr_val __attribute__((unused)); - + static uint8_t snmp_octet_val __attribute__((unused)); #define SNMP_INTEGER(V) \ (*var_len = sizeof(snmp_int_val), snmp_int_val = V, \ (uint8_t *)&snmp_int_val) +#define SNMP_OCTET(V) \ + (*var_len = sizeof(snmp_octet_val), snmp_octet_val = V, \ + (uint8_t *)&snmp_octet_val) + #define SNMP_IPADDRESS(V) \ (*var_len = sizeof(struct in_addr), snmp_in_addr_val = V, \ (uint8_t *)&snmp_in_addr_val) +#define SNMP_IP6ADDRESS(V) (*var_len = sizeof(struct in6_addr), (uint8_t *)&V) + extern void smux_init(struct thread_master *tm); extern void smux_register_mib(const char *, struct variable *, size_t, int, oid[], size_t); @@ -102,10 +135,20 @@ extern int smux_trap(struct variable *, size_t, const oid *, size_t, const oid *, size_t, const oid *, size_t, const struct trap_object *, size_t, uint8_t); +extern int smux_trap_multi_index(struct variable *vp, size_t vp_len, + const oid *ename, size_t enamelen, + const oid *name, size_t namelen, + struct index_oid *iname, size_t index_len, + const struct trap_object *trapobj, + size_t trapobjlen, uint8_t sptrap); extern int oid_compare(const oid *, int, const oid *, int); extern void oid2in_addr(oid[], int, struct in_addr *); +extern void oid2int(oid oid[], int *dest); extern void *oid_copy(void *, const void *, size_t); extern void oid_copy_addr(oid[], const struct in_addr *, int); +extern void oid_copy_int(oid oid[], int *val); +extern void oid2string(oid oid[], int len, char *string); +extern void oid_copy_str(oid oid[], const char *string, int len); #ifdef __cplusplus } diff --git a/lib/snmp.c b/lib/snmp.c index 736a3c62b8..e92f622bb9 100644 --- a/lib/snmp.c +++ b/lib/snmp.c @@ -64,6 +64,19 @@ void oid2in_addr(oid oid[], int len, struct in_addr *addr) *pnt++ = oid[i]; } +void oid2int(oid oid[], int *dest) +{ + uint8_t i; + uint8_t *pnt; + int network_dest; + + pnt = (uint8_t *)&network_dest; + + for (i = 0; i < sizeof(int); i++) + *pnt++ = oid[i]; + *dest = ntohl(network_dest); +} + void oid_copy_addr(oid oid[], const struct in_addr *addr, int len) { int i; @@ -78,6 +91,47 @@ void oid_copy_addr(oid oid[], const struct in_addr *addr, int len) oid[i] = *pnt++; } +void oid_copy_int(oid oid[], int *val) +{ + uint8_t i; + const uint8_t *pnt; + int network_val; + + network_val = htonl(*val); + pnt = (uint8_t *)&network_val; + + for (i = 0; i < sizeof(int); i++) + oid[i] = *pnt++; +} + +void oid2string(oid oid[], int len, char *string) +{ + int i; + uint8_t *pnt; + + if (len == 0) + return; + + pnt = (uint8_t *)string; + + for (i = 0; i < len; i++) + *pnt++ = (uint8_t)oid[i]; +} + +void oid_copy_str(oid oid[], const char *string, int len) +{ + int i; + const uint8_t *pnt; + + if (len == 0) + return; + + pnt = (uint8_t *)string; + + for (i = 0; i < len; i++) + oid[i] = *pnt++; +} + int smux_header_generic(struct variable *v, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { @@ -214,6 +214,53 @@ struct vrf *vrf_get(vrf_id_t vrf_id, const char *name) return vrf; } +/* Update a VRF. If not found, create one. + * Arg: + * name - The name of the vrf. + * vrf_id - The vrf_id of the vrf. + * Description: This function first finds the vrf using its name. If the vrf is + * found and the vrf-id of the existing vrf does not match the new vrf id, it + * will disable the existing vrf and update it with new vrf-id. If the vrf is + * not found, it will create the vrf with given name and the new vrf id. + */ +struct vrf *vrf_update(vrf_id_t new_vrf_id, const char *name) +{ + struct vrf *vrf = NULL; + + /*Treat VRF add for existing vrf as update + * Update VRF ID and also update in VRF ID table + */ + if (name) + vrf = vrf_lookup_by_name(name); + if (vrf && new_vrf_id != VRF_UNKNOWN && vrf->vrf_id != VRF_UNKNOWN + && vrf->vrf_id != new_vrf_id) { + if (debug_vrf) { + zlog_debug( + "Vrf Update event: %s old id: %u, new id: %u", + name, vrf->vrf_id, new_vrf_id); + } + + /*Disable the vrf to simulate implicit delete + * so that all stale routes are deleted + * This vrf will be enabled down the line + */ + vrf_disable(vrf); + + + RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf); + vrf->vrf_id = new_vrf_id; + RB_INSERT(vrf_id_head, &vrfs_by_id, vrf); + + } else { + + /* + * vrf_get is implied creation if it does not exist + */ + vrf = vrf_get(new_vrf_id, name); + } + return vrf; +} + /* Delete a VRF. This is called when the underlying VRF goes away, a * pre-configured VRF is deleted or when shutting down (vrf_terminate()). */ @@ -1064,6 +1111,7 @@ static int lib_vrf_create(struct nb_cb_create_args *args) vrfp = vrf_get(VRF_UNKNOWN, vrfname); + vrf_set_user_cfged(vrfp); nb_running_set_entry(args->dnode, vrfp); return NB_OK; @@ -1089,7 +1137,7 @@ static int lib_vrf_destroy(struct nb_cb_destroy_args *args) vrfp = nb_running_unset_entry(args->dnode); /* Clear configured flag and invoke delete. */ - UNSET_FLAG(vrfp->status, VRF_CONFIGURED); + vrf_reset_user_cfged(vrfp); vrf_delete(vrfp); break; } @@ -114,6 +114,7 @@ extern struct vrf_name_head vrfs_by_name; extern struct vrf *vrf_lookup_by_id(vrf_id_t); extern struct vrf *vrf_lookup_by_name(const char *); extern struct vrf *vrf_get(vrf_id_t, const char *); +extern struct vrf *vrf_update(vrf_id_t new_vrf_id, const char *name); extern const char *vrf_id_to_name(vrf_id_t vrf_id); extern vrf_id_t vrf_name_to_id(const char *); @@ -167,6 +168,20 @@ static inline void vrf_reset_user_cfged(struct vrf *vrf) UNSET_FLAG(vrf->status, VRF_CONFIGURED); } +static inline uint32_t vrf_interface_count(struct vrf *vrf) +{ + uint32_t count = 0; + struct interface *ifp; + + RB_FOREACH (ifp, if_name_head, &vrf->ifaces_by_name) { + /* skip the l3mdev */ + if (strncmp(ifp->name, vrf->name, VRF_NAMSIZ) == 0) + continue; + count++; + } + return count; +} + /* * Utilities to obtain the user data */ |
