diff options
Diffstat (limited to 'ripd/ripd.c')
| -rw-r--r-- | ripd/ripd.c | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/ripd/ripd.c b/ripd/ripd.c index e0ff0430f8..cd2ddb1eba 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -37,7 +37,9 @@ #include "if_rmap.h" #include "plist.h" #include "distribute.h" +#ifdef CRYPTO_INTERNAL #include "md5.h" +#endif #include "keychain.h" #include "privs.h" #include "lib_errors.h" @@ -870,7 +872,11 @@ static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from, struct rip_md5_data *md5data; struct keychain *keychain; struct key *key; +#ifdef CRYPTO_OPENSSL + EVP_MD_CTX *ctx; +#elif CRYPTO_INTERNAL MD5_CTX ctx; +#endif uint8_t digest[RIP_AUTH_MD5_SIZE]; uint16_t packet_len; char auth_str[RIP_AUTH_MD5_SIZE] = {}; @@ -934,11 +940,21 @@ static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from, return 0; /* MD5 digest authentication. */ +#ifdef CRYPTO_OPENSSL + unsigned int md5_size = RIP_AUTH_MD5_SIZE; + ctx = EVP_MD_CTX_new(); + EVP_DigestInit(ctx, EVP_md5()); + EVP_DigestUpdate(ctx, packet, packet_len + RIP_HEADER_SIZE); + EVP_DigestUpdate(ctx, auth_str, RIP_AUTH_MD5_SIZE); + EVP_DigestFinal(ctx, digest, &md5_size); + EVP_MD_CTX_free(ctx); +#elif CRYPTO_INTERNAL memset(&ctx, 0, sizeof(ctx)); MD5Init(&ctx); MD5Update(&ctx, packet, packet_len + RIP_HEADER_SIZE); MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE); MD5Final(digest, &ctx); +#endif if (memcmp(md5data->digest, digest, RIP_AUTH_MD5_SIZE) == 0) return packet_len; @@ -1063,7 +1079,11 @@ static void rip_auth_md5_set(struct stream *s, struct rip_interface *ri, size_t doff, char *auth_str, int authlen) { unsigned long len; +#ifdef CRYPTO_OPENSSL + EVP_MD_CTX *ctx; +#elif CRYPTO_INTERNAL MD5_CTX ctx; +#endif unsigned char digest[RIP_AUTH_MD5_SIZE]; /* Make it sure this interface is configured as MD5 @@ -1092,11 +1112,21 @@ static void rip_auth_md5_set(struct stream *s, struct rip_interface *ri, stream_putw(s, RIP_AUTH_DATA); /* Generate a digest for the RIP packet. */ +#ifdef CRYPTO_OPENSSL + unsigned int md5_size = RIP_AUTH_MD5_SIZE; + ctx = EVP_MD_CTX_new(); + EVP_DigestInit(ctx, EVP_md5()); + EVP_DigestUpdate(ctx, STREAM_DATA(s), stream_get_endp(s)); + EVP_DigestUpdate(ctx, auth_str, RIP_AUTH_MD5_SIZE); + EVP_DigestFinal(ctx, digest, &md5_size); + EVP_MD_CTX_free(ctx); +#elif CRYPTO_INTERNAL memset(&ctx, 0, sizeof(ctx)); MD5Init(&ctx); MD5Update(&ctx, STREAM_DATA(s), stream_get_endp(s)); MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE); MD5Final(digest, &ctx); +#endif /* Copy the digest to the packet. */ stream_write(s, digest, RIP_AUTH_MD5_SIZE); @@ -1365,7 +1395,7 @@ int rip_create_socket(struct vrf *vrf) /* Make datagram socket. */ if (vrf->vrf_id != VRF_DEFAULT) vrf_dev = vrf->name; - frr_elevate_privs(&ripd_privs) { + frr_with_privs(&ripd_privs) { sock = vrf_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, vrf->vrf_id, vrf_dev); if (sock < 0) { @@ -1385,7 +1415,7 @@ int rip_create_socket(struct vrf *vrf) #endif setsockopt_so_recvbuf(sock, RIP_UDP_RCV_BUF); - frr_elevate_privs(&ripd_privs) { + frr_with_privs(&ripd_privs) { if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr))) < 0) { zlog_err("%s: Can't bind socket %d to %s port %d: %s", @@ -3611,6 +3641,41 @@ static int rip_vrf_enable(struct vrf *vrf) int socket; rip = rip_lookup_by_vrf_name(vrf->name); + if (!rip) { + char *old_vrf_name = NULL; + + rip = (struct rip *)vrf->info; + if (!rip) + return 0; + /* update vrf name */ + if (rip->vrf_name) + old_vrf_name = rip->vrf_name; + rip->vrf_name = XSTRDUP(MTYPE_RIP_VRF_NAME, vrf->name); + /* + * HACK: Change the RIP VRF in the running configuration directly, + * bypassing the northbound layer. This is necessary to avoid deleting + * the RIP and readding it in the new VRF, which would have + * several implications. + */ + if (yang_module_find("frr-ripd") && old_vrf_name) { + struct lyd_node *rip_dnode; + + pthread_rwlock_wrlock(&running_config->lock); + { + rip_dnode = yang_dnode_get( + running_config->dnode, + "/frr-ripd:ripd/instance[vrf='%s']/vrf", + old_vrf_name); + if (rip_dnode) { + yang_dnode_change_leaf(rip_dnode, vrf->name); + running_config->version++; + } + } + pthread_rwlock_unlock(&running_config->lock); + } + if (old_vrf_name) + XFREE(MTYPE_RIP_VRF_NAME, old_vrf_name); + } if (!rip || rip->enabled) return 0; @@ -3652,7 +3717,7 @@ static int rip_vrf_disable(struct vrf *vrf) void rip_vrf_init(void) { vrf_init(rip_vrf_new, rip_vrf_enable, rip_vrf_disable, rip_vrf_delete, - NULL); + rip_vrf_enable); } void rip_vrf_terminate(void) |
