#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"
#include "northbound_cli.h"
#include "ripd/ripd.h"
+#include "ripd/rip_nb.h"
#include "ripd/rip_debug.h"
#include "ripd/rip_errors.h"
#include "ripd/rip_interface.h"
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] = {};
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;
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
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);
/* 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) {
#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",
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;
+
+ 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++;
+ }
+ }
+ if (old_vrf_name)
+ XFREE(MTYPE_RIP_VRF_NAME, old_vrf_name);
+ }
if (!rip || rip->enabled)
return 0;
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)