* Add an mfc entry */
| 1048 | * Add an mfc entry |
| 1049 | */ |
| 1050 | static int |
| 1051 | add_mfc(struct mfcctl2 *mfccp) |
| 1052 | { |
| 1053 | struct mfc *rt; |
| 1054 | struct rtdetq *rte, *nrte; |
| 1055 | u_long hash = 0; |
| 1056 | u_short nstl; |
| 1057 | |
| 1058 | VIF_LOCK(); |
| 1059 | MFC_LOCK(); |
| 1060 | |
| 1061 | rt = mfc_find(&mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); |
| 1062 | |
| 1063 | /* If an entry already exists, just update the fields */ |
| 1064 | if (rt) { |
| 1065 | CTR4(KTR_IPMF, "%s: update mfc orig 0x%08x group %lx parent %x", |
| 1066 | __func__, ntohl(mfccp->mfcc_origin.s_addr), |
| 1067 | (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), |
| 1068 | mfccp->mfcc_parent); |
| 1069 | update_mfc_params(rt, mfccp); |
| 1070 | MFC_UNLOCK(); |
| 1071 | VIF_UNLOCK(); |
| 1072 | return (0); |
| 1073 | } |
| 1074 | |
| 1075 | /* |
| 1076 | * Find the entry for which the upcall was made and update |
| 1077 | */ |
| 1078 | nstl = 0; |
| 1079 | hash = MFCHASH(mfccp->mfcc_origin, mfccp->mfcc_mcastgrp); |
| 1080 | LIST_FOREACH(rt, &V_mfchashtbl[hash], mfc_hash) { |
| 1081 | if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) && |
| 1082 | in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp) && |
| 1083 | !TAILQ_EMPTY(&rt->mfc_stall)) { |
| 1084 | CTR5(KTR_IPMF, |
| 1085 | "%s: add mfc orig 0x%08x group %lx parent %x qh %p", |
| 1086 | __func__, ntohl(mfccp->mfcc_origin.s_addr), |
| 1087 | (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr), |
| 1088 | mfccp->mfcc_parent, |
| 1089 | TAILQ_FIRST(&rt->mfc_stall)); |
| 1090 | if (nstl++) |
| 1091 | CTR1(KTR_IPMF, "%s: multiple matches", __func__); |
| 1092 | |
| 1093 | init_mfc_params(rt, mfccp); |
| 1094 | rt->mfc_expire = 0; /* Don't clean this guy up */ |
| 1095 | V_nexpire[hash]--; |
| 1096 | |
| 1097 | /* Free queued packets, but attempt to forward them first. */ |
| 1098 | TAILQ_FOREACH_SAFE(rte, &rt->mfc_stall, rte_link, nrte) { |
| 1099 | if (rte->ifp != NULL) |
| 1100 | ip_mdq(rte->m, rte->ifp, rt, -1); |
| 1101 | m_freem(rte->m); |
| 1102 | TAILQ_REMOVE(&rt->mfc_stall, rte, rte_link); |
| 1103 | rt->mfc_nstall--; |
| 1104 | free(rte, M_MRTABLE); |
| 1105 | } |
| 1106 | } |
| 1107 | } |
no test coverage detected